Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: fix null ref in general account create command #204

Merged
merged 2 commits into from
Jan 4, 2023
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
73 changes: 31 additions & 42 deletions pkg/cmd/account/aws/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ package create

import (
"fmt"
"github.com/OctopusDeploy/cli/pkg/apiclient"
"io"
"github.com/OctopusDeploy/cli/pkg/cmd"
"os"

"github.com/OctopusDeploy/cli/pkg/util"
Expand All @@ -15,13 +14,11 @@ import (
"github.com/OctopusDeploy/cli/pkg/constants"
"github.com/OctopusDeploy/cli/pkg/factory"
"github.com/OctopusDeploy/cli/pkg/output"
"github.com/OctopusDeploy/cli/pkg/question"
"github.com/OctopusDeploy/cli/pkg/question/selectors"
"github.com/OctopusDeploy/cli/pkg/surveyext"
"github.com/OctopusDeploy/cli/pkg/util/flag"
"github.com/OctopusDeploy/cli/pkg/validation"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/accounts"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/client"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/core"
"github.com/spf13/cobra"
)
Expand All @@ -36,13 +33,7 @@ type CreateFlags struct {

type CreateOptions struct {
*CreateFlags
Writer io.Writer
Octopus *client.Client
Ask question.Asker
Space string
Host string
NoPrompt bool
CmdPath string
*cmd.Dependencies
selectors.GetAllEnvironmentsCallback
}

Expand All @@ -56,11 +47,18 @@ func NewCreateFlags() *CreateFlags {
}
}

func NewCmdCreate(f factory.Factory) *cobra.Command {
opts := &CreateOptions{
CreateFlags: NewCreateFlags(),
Ask: f.Ask,
func NewCreateOptions(flags *CreateFlags, dependencies *cmd.Dependencies) *CreateOptions {
return &CreateOptions{
CreateFlags: flags,
Dependencies: dependencies,
GetAllEnvironmentsCallback: func() ([]*environments.Environment, error) {
return selectors.GetAllEnvironments(dependencies.Client)
},
}
}

func NewCmdCreate(f factory.Factory) *cobra.Command {
createFlags := NewCreateFlags()
descriptionFilePath := ""

cmd := &cobra.Command{
Expand All @@ -69,21 +67,10 @@ func NewCmdCreate(f factory.Factory) *cobra.Command {
Long: "Create an AWS account in Octopus Deploy",
Example: heredoc.Docf("$ %s account aws create", constants.ExecutableName),
Aliases: []string{"new"},
RunE: func(cmd *cobra.Command, _ []string) error {
client, err := f.GetSpacedClient(apiclient.NewRequester(cmd))
if err != nil {
return err
}
opts.GetAllEnvironmentsCallback = func() ([]*environments.Environment, error) {
return selectors.GetAllEnvironments(*client)
}
opts.CmdPath = cmd.CommandPath()
opts.Octopus = client
opts.Host = f.GetCurrentHost()
opts.Space = f.GetCurrentSpace().GetID()
opts.Writer = cmd.OutOrStdout()
RunE: func(c *cobra.Command, _ []string) error {
opts := NewCreateOptions(createFlags, cmd.NewDependencies(f, c))
if descriptionFilePath != "" {
if err = validation.IsExistingFile(descriptionFilePath); err != nil {
if err := validation.IsExistingFile(descriptionFilePath); err != nil {
return err
}
data, err := os.ReadFile(descriptionFilePath)
Expand All @@ -92,22 +79,24 @@ func NewCmdCreate(f factory.Factory) *cobra.Command {
}
opts.Description.Value = string(data)
}
opts.NoPrompt = !f.IsPromptEnabled()
if opts.Environments.Value != nil {
opts.Environments.Value, err = helper.ResolveEnvironmentNames(opts.Environments.Value, opts.Octopus)
env, err := helper.ResolveEnvironmentNames(opts.Environments.Value, opts.Client)
if err != nil {
return err
}
opts.Environments.Value = env
}
return CreateRun(opts)
},
}
cmd.Flags().StringVarP(&opts.Name.Value, opts.Name.Name, "n", "", "A short, memorable, unique name for this account.")
cmd.Flags().StringVarP(&opts.Description.Value, opts.Description.Name, "d", "", "A summary explaining the use of the account to other users.")
cmd.Flags().StringVar(&opts.AccessKey.Value, opts.AccessKey.Name, "", "The AWS access key to use when authenticating against Amazon Web Services.")
cmd.Flags().StringVar(&opts.SecretKey.Value, opts.SecretKey.Name, "", "The AWS secret key to use when authenticating against Amazon Web Services.")
cmd.Flags().StringArrayVarP(&opts.Environments.Value, opts.Environments.Name, "e", nil, "The environments that are allowed to use this account")
cmd.Flags().StringVarP(&descriptionFilePath, "description-file", "D", "", "Read the description from `file`")

flags := cmd.Flags()
flags.StringVarP(&createFlags.Name.Value, createFlags.Name.Name, "n", "", "A short, memorable, unique name for this account.")
flags.StringVarP(&createFlags.Description.Value, createFlags.Description.Name, "d", "", "A summary explaining the use of the account to other users.")
flags.StringVar(&createFlags.AccessKey.Value, createFlags.AccessKey.Name, "", "The AWS access key to use when authenticating against Amazon Web Services.")
flags.StringVar(&createFlags.SecretKey.Value, createFlags.SecretKey.Name, "", "The AWS secret key to use when authenticating against Amazon Web Services.")
flags.StringArrayVarP(&createFlags.Environments.Value, createFlags.Environments.Name, "e", nil, "The environments that are allowed to use this account")
flags.StringVarP(&descriptionFilePath, "description-file", "D", "", "Read the description from `file`")

return cmd
}
Expand All @@ -125,20 +114,20 @@ func CreateRun(opts *CreateOptions) error {
awsAccount.Description = opts.Description.Value
awsAccount.EnvironmentIDs = opts.Environments.Value

createdAccount, err := opts.Octopus.Accounts.Add(awsAccount)
createdAccount, err := opts.Client.Accounts.Add(awsAccount)
if err != nil {
return err
}

_, err = fmt.Fprintf(opts.Writer, "Successfully created AWS account %s %s.\n", createdAccount.GetName(), output.Dimf("(%s)", createdAccount.GetSlug()))
_, err = fmt.Fprintf(opts.Out, "Successfully created AWS account %s %s.\n", createdAccount.GetName(), output.Dimf("(%s)", createdAccount.GetSlug()))
if err != nil {
return err
}
link := output.Bluef("%s/app#/%s/infrastructure/accounts/%s", opts.Host, opts.Space, createdAccount.GetID())
fmt.Fprintf(opts.Writer, "\nView this account on Octopus Deploy: %s\n", link)
link := output.Bluef("%s/app#/%s/infrastructure/accounts/%s", opts.Host, opts.Space.GetID(), createdAccount.GetID())
fmt.Fprintf(opts.Out, "\nView this account on Octopus Deploy: %s\n", link)
if !opts.NoPrompt {
autoCmd := flag.GenerateAutomationCmd(opts.CmdPath, opts.Name, opts.AccessKey, opts.SecretKey, opts.Description, opts.Environments)
fmt.Fprintf(opts.Writer, "\nAutomation Command: %s\n", autoCmd)
fmt.Fprintf(opts.Out, "\nAutomation Command: %s\n", autoCmd)
}

return nil
Expand Down
22 changes: 12 additions & 10 deletions pkg/cmd/account/aws/create/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package create_test

import (
"bytes"
"github.com/OctopusDeploy/cli/pkg/cmd"
"net/url"
"testing"

Expand All @@ -28,13 +29,14 @@ var rootResource = testutil.NewRootResource()
func TestAWSAccountCreatePromptMissing(t *testing.T) {
const spaceID = "Space-1"
const envID = "Env-1"
_ = fixtures.NewSpace(spaceID, "testspace")
space := fixtures.NewSpace(spaceID, "testspace")
env := fixtures.NewEnvironment(spaceID, envID, "testenv")
api, qa := testutil.NewMockServerAndAsker()
out := &bytes.Buffer{}

opts := &create.CreateOptions{
CreateFlags: create.NewCreateFlags(),
CreateFlags: create.NewCreateFlags(),
Dependencies: &cmd.Dependencies{Space: space},
GetAllEnvironmentsCallback: func() ([]*environments.Environment, error) {
return []*environments.Environment{env}, nil
},
Expand All @@ -44,8 +46,8 @@ func TestAWSAccountCreatePromptMissing(t *testing.T) {
defer testutil.Close(api, qa)
octopus, _ := octopusApiClient.NewClient(testutil.NewMockHttpClientWithTransport(api), serverUrl, placeholderApiKey, "")
opts.Ask = qa.AsAsker()
opts.Octopus = octopus
opts.Writer = out
opts.Client = octopus
opts.Out = out
return create.PromptMissing(opts)
})

Expand Down Expand Up @@ -93,15 +95,15 @@ func TestAWSAccountCreatePromptMissing(t *testing.T) {
func TestAWSAccountCreateNoPrompt(t *testing.T) {
const spaceID = "Space-1"
const envID = "Env-1"
_ = fixtures.NewSpace(spaceID, "testspace")
space := fixtures.NewSpace(spaceID, "testspace")
_ = fixtures.NewEnvironment(spaceID, envID, "testenv")
api, qa := testutil.NewMockServerAndAsker()
out := &bytes.Buffer{}

opts := &create.CreateOptions{
CreateFlags: create.NewCreateFlags(),
CreateFlags: create.NewCreateFlags(),
Dependencies: &cmd.Dependencies{Space: space},
}
opts.Space = spaceID
opts.Name.Value = "testaccount"
opts.AccessKey.Value = "testaccesskey123"
opts.SecretKey.Value = "testsecretkey123"
Expand All @@ -110,8 +112,8 @@ func TestAWSAccountCreateNoPrompt(t *testing.T) {
defer testutil.Close(api, qa)
octopus, _ := octopusApiClient.NewClient(testutil.NewMockHttpClientWithTransport(api), serverUrl, placeholderApiKey, "")
opts.Ask = qa.AsAsker()
opts.Octopus = octopus
opts.Writer = out
opts.Client = octopus
opts.Out = out
opts.NoPrompt = true
return create.CreateRun(opts)
})
Expand Down Expand Up @@ -139,6 +141,6 @@ func TestAWSAccountCreateNoPrompt(t *testing.T) {
`,
testAccount.Name,
output.Dimf("(%s)", testAccount.Slug),
output.Bluef("%s/app#/%s/infrastructure/accounts/%s", "", opts.Space, testAccount.ID),
output.Bluef("%s/app#/%s/infrastructure/accounts/%s", "", opts.Space.GetID(), testAccount.ID),
), res)
}
81 changes: 34 additions & 47 deletions pkg/cmd/account/azure/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ package create

import (
"fmt"
"github.com/OctopusDeploy/cli/pkg/apiclient"
"io"
"github.com/OctopusDeploy/cli/pkg/cmd"
"os"
"strings"

Expand All @@ -16,13 +15,11 @@ import (
"github.com/OctopusDeploy/cli/pkg/constants"
"github.com/OctopusDeploy/cli/pkg/factory"
"github.com/OctopusDeploy/cli/pkg/output"
"github.com/OctopusDeploy/cli/pkg/question"
"github.com/OctopusDeploy/cli/pkg/question/selectors"
"github.com/OctopusDeploy/cli/pkg/surveyext"
"github.com/OctopusDeploy/cli/pkg/util/flag"
"github.com/OctopusDeploy/cli/pkg/validation"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/accounts"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/client"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/core"
"github.com/google/uuid"
"github.com/spf13/cobra"
Expand All @@ -43,13 +40,7 @@ type CreateFlags struct {

type CreateOptions struct {
*CreateFlags
Writer io.Writer
Octopus *client.Client
Ask question.Asker
Space string
NoPrompt bool
Host string
CmdPath string
*cmd.Dependencies
selectors.GetAllEnvironmentsCallback
}

Expand All @@ -68,6 +59,16 @@ func NewCreateFlags() *CreateFlags {
}
}

func NewCreateOptions(flags *CreateFlags, dependencies *cmd.Dependencies) *CreateOptions {
return &CreateOptions{
CreateFlags: flags,
Dependencies: dependencies,
GetAllEnvironmentsCallback: func() ([]*environments.Environment, error) {
return selectors.GetAllEnvironments(dependencies.Client)
},
}
}

var azureEnvMap = map[string]string{
"Global Cloud (Default)": "AzureCloud",
"China Cloud": "AzureChinaCloud",
Expand All @@ -88,10 +89,7 @@ var azureResourceManagementBaseUri = map[string]string{
}

func NewCmdCreate(f factory.Factory) *cobra.Command {
opts := &CreateOptions{
Ask: f.Ask,
CreateFlags: NewCreateFlags(),
}
createFlags := NewCreateFlags()
descriptionFilePath := ""

cmd := &cobra.Command{
Expand All @@ -100,21 +98,8 @@ func NewCmdCreate(f factory.Factory) *cobra.Command {
Long: "Create an Azure subscription account in Octopus Deploy",
Example: heredoc.Docf("$ %s account azure create", constants.ExecutableName),
Aliases: []string{"new"},
RunE: func(cmd *cobra.Command, _ []string) error {
client, err := f.GetSpacedClient(apiclient.NewRequester(cmd))
if err != nil {
return err
}

opts.GetAllEnvironmentsCallback = func() ([]*environments.Environment, error) {
return selectors.GetAllEnvironments(*client)
}

opts.CmdPath = cmd.CommandPath()
opts.Host = f.GetCurrentHost()
opts.Space = f.GetCurrentSpace().GetID()
opts.Octopus = client
opts.Writer = cmd.OutOrStdout()
RunE: func(c *cobra.Command, _ []string) error {
opts := NewCreateOptions(createFlags, cmd.NewDependencies(f, c))
if descriptionFilePath != "" {
if err := validation.IsExistingFile(descriptionFilePath); err != nil {
return err
Expand Down Expand Up @@ -162,26 +147,28 @@ func NewCmdCreate(f factory.Factory) *cobra.Command {
}
}
if opts.Environments.Value != nil {
opts.Environments.Value, err = helper.ResolveEnvironmentNames(opts.Environments.Value, opts.Octopus)
env, err := helper.ResolveEnvironmentNames(opts.Environments.Value, opts.Client)
if err != nil {
return err
}
opts.Environments.Value = env
}
return CreateRun(opts)
},
}

cmd.Flags().StringVarP(&opts.Name.Value, opts.Name.Name, "n", "", "A short, memorable, unique name for this account.")
cmd.Flags().StringVarP(&opts.Description.Value, opts.Description.Value, "d", "", "A summary explaining the use of the account to other users.")
cmd.Flags().StringVar(&opts.SubscriptionID.Value, opts.SubscriptionID.Name, "", "Your Azure subscription ID.")
cmd.Flags().StringVar(&opts.TenantID.Value, opts.TenantID.Name, "", "Your Azure Active Directory Tenant ID.")
cmd.Flags().StringVar(&opts.ApplicationID.Value, opts.ApplicationID.Name, "", "Your Azure Active Directory Application ID.")
cmd.Flags().StringVar(&opts.ApplicationPasswordKey.Value, opts.ApplicationPasswordKey.Name, "", "The password for the Azure Active Directory application.")
cmd.Flags().StringArrayVarP(&opts.Environments.Value, opts.Environments.Name, "e", nil, "The environments that are allowed to use this account")
cmd.Flags().StringVar(&opts.AzureEnvironment.Value, opts.AzureEnvironment.Name, "", "Set only if you are using an isolated Azure Environment. Configure isolated Azure Environment. Valid option are AzureChinaCloud, AzureChinaCloud, AzureGermanCloud or AzureUSGovernment")
cmd.Flags().StringVar(&opts.ADEndpointBaseUrl.Value, opts.ADEndpointBaseUrl.Name, "", "Set this only if you need to override the default Active Directory Endpoint.")
cmd.Flags().StringVar(&opts.RMBaseUri.Value, opts.RMBaseUri.Name, "", "Set this only if you need to override the default Resource Management Endpoint.")
cmd.Flags().StringVarP(&descriptionFilePath, "description-file", "D", "", "Read the description from `file`")
flags := cmd.Flags()
flags.StringVarP(&createFlags.Name.Value, createFlags.Name.Name, "n", "", "A short, memorable, unique name for this account.")
flags.StringVarP(&createFlags.Description.Value, createFlags.Description.Value, "d", "", "A summary explaining the use of the account to other users.")
flags.StringVar(&createFlags.SubscriptionID.Value, createFlags.SubscriptionID.Name, "", "Your Azure subscription ID.")
flags.StringVar(&createFlags.TenantID.Value, createFlags.TenantID.Name, "", "Your Azure Active Directory Tenant ID.")
flags.StringVar(&createFlags.ApplicationID.Value, createFlags.ApplicationID.Name, "", "Your Azure Active Directory Application ID.")
flags.StringVar(&createFlags.ApplicationPasswordKey.Value, createFlags.ApplicationPasswordKey.Name, "", "The password for the Azure Active Directory application.")
flags.StringArrayVarP(&createFlags.Environments.Value, createFlags.Environments.Name, "e", nil, "The environments that are allowed to use this account")
flags.StringVar(&createFlags.AzureEnvironment.Value, createFlags.AzureEnvironment.Name, "", "Set only if you are using an isolated Azure Environment. Configure isolated Azure Environment. Valid option are AzureChinaCloud, AzureChinaCloud, AzureGermanCloud or AzureUSGovernment")
flags.StringVar(&createFlags.ADEndpointBaseUrl.Value, createFlags.ADEndpointBaseUrl.Name, "", "Set this only if you need to override the default Active Directory Endpoint.")
flags.StringVar(&createFlags.RMBaseUri.Value, createFlags.RMBaseUri.Name, "", "Set this only if you need to override the default Resource Management Endpoint.")
flags.StringVarP(&descriptionFilePath, "description-file", "D", "", "Read the description from `file`")

return cmd
}
Expand Down Expand Up @@ -220,17 +207,17 @@ func CreateRun(opts *CreateOptions) error {
servicePrincipalAccount.ResourceManagerEndpoint = opts.RMBaseUri.Value
servicePrincipalAccount.AuthenticationEndpoint = opts.ADEndpointBaseUrl.Value

createdAccount, err = opts.Octopus.Accounts.Add(servicePrincipalAccount)
createdAccount, err = opts.Client.Accounts.Add(servicePrincipalAccount)
if err != nil {
return err
}

_, err = fmt.Fprintf(opts.Writer, "Successfully created Azure account %s %s.\n", createdAccount.GetName(), output.Dimf("(%s)", createdAccount.GetSlug()))
_, err = fmt.Fprintf(opts.Out, "Successfully created Azure account %s %s.\n", createdAccount.GetName(), output.Dimf("(%s)", createdAccount.GetSlug()))
if err != nil {
return err
}
link := output.Bluef("%s/app#/%s/infrastructure/accounts/%s", opts.Host, opts.Space, createdAccount.GetID())
fmt.Fprintf(opts.Writer, "\nView this account on Octopus Deploy: %s\n", link)
link := output.Bluef("%s/app#/%s/infrastructure/accounts/%s", opts.Host, opts.Space.GetID(), createdAccount.GetID())
fmt.Fprintf(opts.Out, "\nView this account on Octopus Deploy: %s\n", link)
if !opts.NoPrompt {
autoCmd := flag.GenerateAutomationCmd(
opts.CmdPath,
Expand All @@ -245,7 +232,7 @@ func CreateRun(opts *CreateOptions) error {
opts.ADEndpointBaseUrl,
opts.RMBaseUri,
)
fmt.Fprintf(opts.Writer, "\nAutomation Command: %s\n", autoCmd)
fmt.Fprintf(opts.Out, "\nAutomation Command: %s\n", autoCmd)
}
return nil
}
Expand Down
Loading