Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions pkg/cmd/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ func NewCommand(config *config.CLIConfig, streams io.ReadWriter, groupID string)
cmd.AddCommand(newIdentitySourceCommand(config, streams))
cmd.AddCommand(newAPIClientCommand(config, streams))
cmd.AddCommand(newApplicationCommand(config, streams))
cmd.AddCommand(newIdentityAgentCommand(config, streams))
cmd.AddCommand(newPasswordPolicyCommand(config, streams))

return cmd
Expand Down Expand Up @@ -166,6 +167,10 @@ func (o *options) Run(cmd *cobra.Command, args []string) error {
options := &applicationOptions{}
err = options.createApplicationFromDataMap(cmd, resourceObject.Data.(map[string]interface{}))

case resource.ResourceTypePrefix + "IdentityAgent":
options := &identityAgentOptions{}
err = options.createIdentityAgentFromDataMap(cmd, resourceObject.Data.(map[string]interface{}))

case resource.ResourceTypePrefix + "PasswordPolicy":
options := &passwordPolicyOptions{}
err = options.createPasswordPolicyFromDataMap(cmd, resourceObject.Data.(map[string]interface{}))
Expand Down
196 changes: 196 additions & 0 deletions pkg/cmd/create/identity_agent.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
package create

import (
"encoding/json"
"io"
"os"

"github.com/ibm-verify/verify-sdk-go/pkg/config/integrations"
"github.com/ibm-verify/verifyctl/pkg/cmd/resource"
"github.com/ibm-verify/verifyctl/pkg/config"
cmdutil "github.com/ibm-verify/verifyctl/pkg/util/cmd"
"github.com/ibm-verify/verifyctl/pkg/util/templates"

contextx "github.com/ibm-verify/verify-sdk-go/pkg/core/context"
errorsx "github.com/ibm-verify/verify-sdk-go/pkg/core/errors"
"github.com/spf13/cobra"
)

const (
identityAgentUsage = "identityagent [options]"
identityAgentMessagePrefix = "CreateIdentityAgent"
identityAgentEntitlements = "Manage Identity Agents"
identityAgentResourceName = "identityagent"
)

var (
identityAgentShortDesc = cmdutil.TranslateShortDesc(identityAgentMessagePrefix, "Options to create an Identity Agent.")

identityAgentLongDesc = templates.LongDesc(cmdutil.TranslateLongDesc(identityAgentMessagePrefix, `
Options to create an Identity Agent.

Identity Agents on Verify require specific entitlements, so ensure that the Identity Agent used
with the 'auth' command has the required entitlements.

An empty resource file can be generated using:

verifyctl create identityagent --purpose=PROV --boilerplate

You can check required entitlements by running:

verifyctl create identityagent --entitlements`))

identityAgentExamples = templates.Examples(cmdutil.TranslateExamples(identityAgentMessagePrefix, `
# Create an empty Identity agent resource.
verifyctl create identityagent --boilerplate

# Create an Identity Agent using a JSON file.
verifyctl create identityagent -f=./identityagent.json`))
)

type identityAgentOptions struct {
options
purpose string
config *config.CLIConfig
}

func newIdentityAgentCommand(config *config.CLIConfig, streams io.ReadWriter) *cobra.Command {
o := &identityAgentOptions{
config: config,
}

cmd := &cobra.Command{
Use: identityAgentUsage,
Short: identityAgentShortDesc,
Long: identityAgentLongDesc,
Example: identityAgentExamples,
DisableFlagsInUseLine: true,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.ExitOnError(cmd, o.Complete(cmd, args))
cmdutil.ExitOnError(cmd, o.Validate(cmd, args))
cmdutil.ExitOnError(cmd, o.Run(cmd, args))
},
}

cmd.SetOut(streams)
cmd.SetErr(streams)
cmd.SetIn(streams)

o.AddFlags(cmd)

return cmd
}

func (o *identityAgentOptions) AddFlags(cmd *cobra.Command) {
o.addCommonFlags(cmd, identityAgentResourceName)
cmd.Flags().StringVarP(&o.file, "file", "f", "", "Path to the yaml file containing Identity Agent data.")
cmd.Flags().StringVarP(&o.purpose, "purpose", "p", "", "Purpose of the Identity Agent, [PROV, LDAPAUTH, EXTAUTHN]")
}

func (o *identityAgentOptions) Complete(cmd *cobra.Command, args []string) error {
return nil
}

func (o *identityAgentOptions) Validate(cmd *cobra.Command, args []string) error {
if o.entitlements || o.boilerplate {
return nil
}

if len(o.file) == 0 {
return errorsx.G11NError("The 'file' option is required if no other options are used.")
}
return nil
}

func (o *identityAgentOptions) Run(cmd *cobra.Command, args []string) error {
if o.entitlements {
cmdutil.WriteString(cmd, entitlementsMessage+" "+identityAgentEntitlements)
return nil
}

if o.boilerplate {
if o.purpose == "PROV" || o.purpose == "LDAPAUTH" || o.purpose == "EXTAUTHN" || o.purpose == "" {
resourceObj := &resource.ResourceObject{
Kind: resource.ResourceTypePrefix + "IdentityAgent",
APIVersion: "1.0",
Data: integrations.IdentityAgentExample(o.purpose),
}

cmdutil.WriteAsYAML(cmd, resourceObj, cmd.OutOrStdout())
return nil
} else {
return errorsx.G11NError("unknown purpose")
}
}

_, err := o.config.GetCurrentAuth()
if err != nil {
return err
}

return o.createIdentityAgent(cmd)
}

func (o *identityAgentOptions) createIdentityAgent(cmd *cobra.Command) error {
ctx := cmd.Context()
vc := contextx.GetVerifyContext(ctx)

b, err := os.ReadFile(o.file)
if err != nil {
vc.Logger.Errorf("unable to read file; filename=%s, err=%v", o.file, err)
return err
}

return o.createIdentityAgentWithData(cmd, b)
}

func (o *identityAgentOptions) createIdentityAgentWithData(cmd *cobra.Command, data []byte) error {
ctx := cmd.Context()
vc := contextx.GetVerifyContext(ctx)

identityAgentConfig := &integrations.IdentityAgentConfig{}
if err := json.Unmarshal(data, &identityAgentConfig); err != nil {
vc.Logger.Errorf("unable to unmarshal Identity Agent; err=%v", err)
return err
}

client := integrations.NewIdentityAgentClient()
resourceURI, err := client.CreateIdentityAgent(ctx, identityAgentConfig)
if err != nil {
vc.Logger.Errorf("failed to create Identity Agent; err=%v", err)
return err
}

cmdutil.WriteString(cmd, "Resource created: "+resourceURI)
return nil
}

func (o *identityAgentOptions) createIdentityAgentFromDataMap(cmd *cobra.Command, data map[string]interface{}) error {
ctx := cmd.Context()
vc := contextx.GetVerifyContext(ctx)

// Convert map data to JSON
identityAgentConfig := &integrations.IdentityAgentConfig{}
b, err := json.Marshal(data)
if err != nil {
vc.Logger.Errorf("failed to marshal data; err=%v", err)
return err
}

if err := json.Unmarshal(b, identityAgentConfig); err != nil {
vc.Logger.Errorf("unable to unmarshal data to Identoty Agent; err=%v", err)
return err
}

// Create Identity Agent
client := integrations.NewIdentityAgentClient()
resourceURI, err := client.CreateIdentityAgent(ctx, identityAgentConfig)
if err != nil {
vc.Logger.Errorf("failed to create Identity Agent; err=%v", err)
return err
}

// Directly return the created resource URI
cmdutil.WriteString(cmd, "Resource created: "+resourceURI)
return nil
}
1 change: 1 addition & 0 deletions pkg/cmd/delete/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ func NewCommand(config *config.CLIConfig, streams io.ReadWriter, groupID string)
cmd.AddCommand(NewIdentitySourceCommand(config, streams))
cmd.AddCommand(NewAPIClientCommand(config, streams))
cmd.AddCommand(NewApplicationCommand(config, streams))
cmd.AddCommand(NewIdentityAgentCommand(config, streams))
cmd.AddCommand(NewPasswordPolicyCommand(config, streams))

return cmd
Expand Down
131 changes: 131 additions & 0 deletions pkg/cmd/delete/identity_agent.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package delete

import (
"io"

"github.com/ibm-verify/verify-sdk-go/pkg/config/integrations"
"github.com/ibm-verify/verify-sdk-go/pkg/i18n"
"github.com/ibm-verify/verifyctl/pkg/config"
cmdutil "github.com/ibm-verify/verifyctl/pkg/util/cmd"
"github.com/ibm-verify/verifyctl/pkg/util/templates"
"github.com/spf13/cobra"

errorsx "github.com/ibm-verify/verify-sdk-go/pkg/core/errors"
)

const (
identityAgentUsage = `identityagent [flags]`
identityAgentMessagePrefix = "DeleteIdentityAgent"
identityAgentEntitlements = "Manage identityAgents"
identityAgentResourceName = "identityagent"
)

var (
identityAgentLongDesc = templates.LongDesc(cmdutil.TranslateLongDesc(identityAgentMessagePrefix, `
Delete Identity Agent based on identityAgentID.

Resources managed on Verify have specific entitlements, so ensure that the Identity agents used
with the 'auth' command is configured with the appropriate entitlements.

You can identify the entitlement required by running:

verifyctl delete identityagent --entitlements`))

identityAgentExamples = templates.Examples(cmdutil.TranslateExamples(messagePrefix, `
# Delete an Identity Agent by ID
verifyctl delete identityagent --identityAgentID="12345"`,
))
)

type identityAgentsOptions struct {
options
identityAgentID string
config *config.CLIConfig
}

func NewIdentityAgentCommand(config *config.CLIConfig, streams io.ReadWriter) *cobra.Command {
o := &identityAgentsOptions{
config: config,
}

cmd := &cobra.Command{
Use: identityAgentUsage,
Short: cmdutil.TranslateShortDesc(identityAgentMessagePrefix, "Delete Identity Agent based on its id."),
Long: identityAgentLongDesc,
Example: identityAgentExamples,
DisableFlagsInUseLine: true,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.ExitOnError(cmd, o.Complete(cmd, args))
cmdutil.ExitOnError(cmd, o.Validate(cmd, args))
cmdutil.ExitOnError(cmd, o.Run(cmd, args))
},
}

cmd.SetOut(streams)
cmd.SetErr(streams)
cmd.SetIn(streams)

o.AddFlags(cmd)

return cmd
}

func (o *identityAgentsOptions) AddFlags(cmd *cobra.Command) {
o.addCommonFlags(cmd)
cmd.Flags().StringVar(&o.identityAgentID, "identityAgentID", o.identityAgentID, i18n.Translate("identityAgentID to be deleted"))
}

func (o *identityAgentsOptions) Complete(cmd *cobra.Command, args []string) error {
return nil
}

func (o *identityAgentsOptions) Validate(cmd *cobra.Command, args []string) error {
if o.entitlements {
return nil
}

calledAs := cmd.CalledAs()
if calledAs == "identityagent" && o.identityAgentID == "" {
return errorsx.G11NError("'identityAgentID' flag is required")
}
return nil
}

func (o *identityAgentsOptions) Run(cmd *cobra.Command, args []string) error {
if o.entitlements {
cmdutil.WriteString(cmd, entitlementsMessage+" "+identityAgentEntitlements)
return nil
}

_, err := o.config.SetAuthToContext(cmd.Context())
if err != nil {
return err
}

// invoke the operation
if cmd.CalledAs() == "identityagent" {
// deal with single Identity Agent
return o.handleSingleIdentityAgent(cmd, args)
}
return nil
}

func (o *identityAgentsOptions) handleSingleIdentityAgent(cmd *cobra.Command, _ []string) error {
c := integrations.NewIdentityAgentClient()
var id string
var err error

if o.identityAgentID != "" {
id = o.identityAgentID
err = c.DeleteIdentityAgentByID(cmd.Context(), id)
if err != nil {
return err
}
} else {
return errorsx.G11NError("either clientName or clientId must be provided")
}

resourceIdentifier := o.identityAgentID
cmdutil.WriteString(cmd, "Resource deleted with ID: "+resourceIdentifier)
return nil
}
1 change: 1 addition & 0 deletions pkg/cmd/get/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ func NewCommand(config *config.CLIConfig, streams io.ReadWriter, groupID string)
cmd.AddCommand(NewIdentitySourceCommand(config, streams))
cmd.AddCommand(NewAPIClientsCommand(config, streams))
cmd.AddCommand(NewApplicationsCommand(config, streams))
cmd.AddCommand(NewIdentityAgentsCommand(config, streams))
cmd.AddCommand(newPasswordPolicyCommand(config, streams))

return cmd
Expand Down
Loading