diff --git a/internal/pkg/cli/app_show.go b/internal/pkg/cli/app_show.go index a996af17779..19ad5570576 100644 --- a/internal/pkg/cli/app_show.go +++ b/internal/pkg/cli/app_show.go @@ -217,14 +217,15 @@ func (o *showAppOpts) description() (*describe.App, error) { return nil, fmt.Errorf("get version for application %s: %w", o.name, err) } return &describe.App{ - Name: app.Name, - Version: version, - URI: app.Domain, - Envs: trimmedEnvs, - Services: trimmedSvcs, - Jobs: trimmedJobs, - Pipelines: pipelineInfo, - WkldDeployedtoEnvs: wkldDeployedtoEnvs, + Name: app.Name, + Version: version, + URI: app.Domain, + PermissionsBoundary: app.PermissionsBoundary, + Envs: trimmedEnvs, + Services: trimmedSvcs, + Jobs: trimmedJobs, + Pipelines: pipelineInfo, + WkldDeployedtoEnvs: wkldDeployedtoEnvs, }, nil } diff --git a/internal/pkg/cli/app_show_test.go b/internal/pkg/cli/app_show_test.go index b179636e6b9..03e4b4d454d 100644 --- a/internal/pkg/cli/app_show_test.go +++ b/internal/pkg/cli/app_show_test.go @@ -188,8 +188,9 @@ func TestShowAppOpts_Execute(t *testing.T) { setupMocks: func(m showAppMocks) { m.storeSvc.EXPECT().GetApplication("my-app").Return(&config.Application{ - Name: "my-app", - Domain: "example.com", + Name: "my-app", + Domain: "example.com", + PermissionsBoundary: "examplePermissionsBoundaryPolicy", }, nil) m.storeSvc.EXPECT().ListServices("my-app").Return([]*config.Workload{ { @@ -231,13 +232,14 @@ func TestShowAppOpts_Execute(t *testing.T) { m.versionGetter.EXPECT().Version().Return("v0.0.0", nil) }, - wantedContent: "{\"name\":\"my-app\",\"version\":\"v0.0.0\",\"uri\":\"example.com\",\"environments\":[{\"app\":\"\",\"name\":\"test\",\"region\":\"us-west-2\",\"accountID\":\"123456789\",\"registryURL\":\"\",\"executionRoleARN\":\"\",\"managerRoleARN\":\"\"},{\"app\":\"\",\"name\":\"prod\",\"region\":\"us-west-1\",\"accountID\":\"123456789\",\"registryURL\":\"\",\"executionRoleARN\":\"\",\"managerRoleARN\":\"\"}],\"services\":[{\"app\":\"\",\"name\":\"my-svc\",\"type\":\"lb-web-svc\"}],\"jobs\":[{\"app\":\"\",\"name\":\"my-job\",\"type\":\"Scheduled Job\"}],\"pipelines\":[{\"pipelineName\":\"my-pipeline-repo\",\"region\":\"\",\"accountId\":\"\",\"stages\":null,\"createdAt\":\"0001-01-01T00:00:00Z\",\"updatedAt\":\"0001-01-01T00:00:00Z\"},{\"pipelineName\":\"bad-goose\",\"region\":\"\",\"accountId\":\"\",\"stages\":null,\"createdAt\":\"0001-01-01T00:00:00Z\",\"updatedAt\":\"0001-01-01T00:00:00Z\"}]}\n", + wantedContent: "{\"name\":\"my-app\",\"version\":\"v0.0.0\",\"uri\":\"example.com\",\"permissionsBoundary\":\"examplePermissionsBoundaryPolicy\",\"environments\":[{\"app\":\"\",\"name\":\"test\",\"region\":\"us-west-2\",\"accountID\":\"123456789\",\"registryURL\":\"\",\"executionRoleARN\":\"\",\"managerRoleARN\":\"\"},{\"app\":\"\",\"name\":\"prod\",\"region\":\"us-west-1\",\"accountID\":\"123456789\",\"registryURL\":\"\",\"executionRoleARN\":\"\",\"managerRoleARN\":\"\"}],\"services\":[{\"app\":\"\",\"name\":\"my-svc\",\"type\":\"lb-web-svc\"}],\"jobs\":[{\"app\":\"\",\"name\":\"my-job\",\"type\":\"Scheduled Job\"}],\"pipelines\":[{\"pipelineName\":\"my-pipeline-repo\",\"region\":\"\",\"accountId\":\"\",\"stages\":null,\"createdAt\":\"0001-01-01T00:00:00Z\",\"updatedAt\":\"0001-01-01T00:00:00Z\"},{\"pipelineName\":\"bad-goose\",\"region\":\"\",\"accountId\":\"\",\"stages\":null,\"createdAt\":\"0001-01-01T00:00:00Z\",\"updatedAt\":\"0001-01-01T00:00:00Z\"}]}\n", }, "correctly shows human output": { setupMocks: func(m showAppMocks) { m.storeSvc.EXPECT().GetApplication("my-app").Return(&config.Application{ - Name: "my-app", - Domain: "example.com", + Name: "my-app", + Domain: "example.com", + PermissionsBoundary: "examplePermissionsBoundaryPolicy", }, nil) m.storeSvc.EXPECT().ListServices("my-app").Return([]*config.Workload{ { @@ -281,9 +283,10 @@ func TestShowAppOpts_Execute(t *testing.T) { wantedContent: `About - Name my-app - Version v0.0.0 (latest available: v1.1.0) - URI example.com + Name my-app + Version v0.0.0 (latest available: v1.1.0) + URI example.com + Permissions Boundary examplePermissionsBoundaryPolicy Environments @@ -310,8 +313,9 @@ Pipelines "correctly shows human output with latest version": { setupMocks: func(m showAppMocks) { m.storeSvc.EXPECT().GetApplication("my-app").Return(&config.Application{ - Name: "my-app", - Domain: "example.com", + Name: "my-app", + Domain: "example.com", + PermissionsBoundary: "examplePermissionsBoundaryPolicy", }, nil) m.storeSvc.EXPECT().ListServices("my-app").Return([]*config.Workload{ { @@ -347,9 +351,77 @@ Pipelines wantedContent: `About - Name my-app - Version v1.1.0 - URI example.com + Name my-app + Version v1.1.0 + URI example.com + Permissions Boundary examplePermissionsBoundaryPolicy + +Environments + + Name AccountID Region + ---- --------- ------ + test 123456789 us-west-2 + prod 123456789 us-west-1 + +Workloads + + Name Type Environments + ---- ---- ------------ + my-svc lb-web-svc prod, test + my-job Scheduled Job prod, test + +Pipelines + + Name + ---- +`, + }, + "correctly shows human output when URI and Permissions Boundary are empty": { + setupMocks: func(m showAppMocks) { + m.storeSvc.EXPECT().GetApplication("my-app").Return(&config.Application{ + Name: "my-app", + Domain: "", + PermissionsBoundary: "", + }, nil) + m.storeSvc.EXPECT().ListServices("my-app").Return([]*config.Workload{ + { + Name: "my-svc", + Type: "lb-web-svc", + }, + }, nil) + m.storeSvc.EXPECT().ListJobs("my-app").Return([]*config.Workload{ + { + Name: "my-job", + Type: "Scheduled Job", + }, + }, nil) + m.storeSvc.EXPECT().ListEnvironments("my-app").Return([]*config.Environment{ + { + Name: "test", + Region: "us-west-2", + AccountID: "123456789", + }, + { + Name: "prod", + AccountID: "123456789", + Region: "us-west-1", + }, + }, nil) + m.deployStore.EXPECT().ListDeployedJobs("my-app", "test").Return([]string{"my-job"}, nil) + m.deployStore.EXPECT().ListDeployedJobs("my-app", "prod").Return([]string{"my-job"}, nil) + m.deployStore.EXPECT().ListDeployedServices("my-app", "test").Return([]string{"my-svc"}, nil) + m.deployStore.EXPECT().ListDeployedServices("my-app", "prod").Return([]string{"my-svc"}, nil) + m.pipelineLister.EXPECT().ListDeployedPipelines(mockAppName).Return([]deploy.Pipeline{}, nil) + m.versionGetter.EXPECT().Version().Return(deploy.LatestAppTemplateVersion, nil) + + }, + + wantedContent: `About + + Name my-app + Version v1.1.0 + URI N/A + Permissions Boundary N/A Environments @@ -374,8 +446,9 @@ Pipelines "when service/job is not deployed": { setupMocks: func(m showAppMocks) { m.storeSvc.EXPECT().GetApplication("my-app").Return(&config.Application{ - Name: "my-app", - Domain: "example.com", + Name: "my-app", + Domain: "example.com", + PermissionsBoundary: "examplePermissionsBoundaryPolicy", }, nil) m.storeSvc.EXPECT().ListServices("my-app").Return([]*config.Workload{ { @@ -415,9 +488,10 @@ Pipelines wantedContent: `About - Name my-app - Version v1.1.0 - URI example.com + Name my-app + Version v1.1.0 + URI example.com + Permissions Boundary examplePermissionsBoundaryPolicy Environments @@ -442,8 +516,9 @@ Pipelines }, "when multiple services/jobs are deployed": { setupMocks: func(m showAppMocks) { m.storeSvc.EXPECT().GetApplication("my-app").Return(&config.Application{ - Name: "my-app", - Domain: "example.com", + Name: "my-app", + Domain: "example.com", + PermissionsBoundary: "examplePermissionsBoundaryPolicy", }, nil) m.storeSvc.EXPECT().ListServices("my-app").Return([]*config.Workload{ { @@ -504,9 +579,10 @@ Pipelines wantedContent: `About - Name my-app - Version v1.1.0 - URI example.com + Name my-app + Version v1.1.0 + URI example.com + Permissions Boundary examplePermissionsBoundaryPolicy Environments @@ -544,8 +620,9 @@ Pipelines "returns error if fail to list environment": { setupMocks: func(m showAppMocks) { m.storeSvc.EXPECT().GetApplication("my-app").Return(&config.Application{ - Name: "my-app", - Domain: "example.com", + Name: "my-app", + Domain: "example.com", + PermissionsBoundary: "examplePermissionsBoundaryPolicy", }, nil) m.storeSvc.EXPECT().ListEnvironments("my-app").Return(nil, testError) }, @@ -557,8 +634,9 @@ Pipelines setupMocks: func(m showAppMocks) { m.storeSvc.EXPECT().GetApplication("my-app").Return(&config.Application{ - Name: "my-app", - Domain: "example.com", + Name: "my-app", + Domain: "example.com", + PermissionsBoundary: "examplePermissionsBoundaryPolicy", }, nil) m.storeSvc.EXPECT().ListEnvironments("my-app").Return([]*config.Environment{ { @@ -582,8 +660,9 @@ Pipelines setupMocks: func(m showAppMocks) { m.storeSvc.EXPECT().GetApplication("my-app").Return(&config.Application{ - Name: "my-app", - Domain: "example.com", + Name: "my-app", + Domain: "example.com", + PermissionsBoundary: "examplePermissionsBoundaryPolicy", }, nil) m.storeSvc.EXPECT().ListEnvironments("my-app").Return([]*config.Environment{ { @@ -613,8 +692,9 @@ Pipelines setupMocks: func(m showAppMocks) { m.storeSvc.EXPECT().GetApplication("my-app").Return(&config.Application{ - Name: "my-app", - Domain: "example.com", + Name: "my-app", + Domain: "example.com", + PermissionsBoundary: "examplePermissionsBoundaryPolicy", }, nil) m.storeSvc.EXPECT().ListEnvironments("my-app").Return([]*config.Environment{ { @@ -653,8 +733,9 @@ Pipelines setupMocks: func(m showAppMocks) { m.storeSvc.EXPECT().GetApplication("my-app").Return(&config.Application{ - Name: "my-app", - Domain: "example.com", + Name: "my-app", + Domain: "example.com", + PermissionsBoundary: "examplePermissionsBoundaryPolicy", }, nil) m.storeSvc.EXPECT().ListEnvironments("my-app").Return([]*config.Environment{ { @@ -695,8 +776,9 @@ Pipelines setupMocks: func(m showAppMocks) { m.storeSvc.EXPECT().GetApplication("my-app").Return(&config.Application{ - Name: "my-app", - Domain: "example.com", + Name: "my-app", + Domain: "example.com", + PermissionsBoundary: "examplePermissionsBoundaryPolicy", }, nil) m.storeSvc.EXPECT().ListEnvironments("my-app").Return([]*config.Environment{ { diff --git a/internal/pkg/describe/app.go b/internal/pkg/describe/app.go index 60a99dfc274..14265be48a4 100644 --- a/internal/pkg/describe/app.go +++ b/internal/pkg/describe/app.go @@ -23,14 +23,15 @@ import ( // App contains serialized parameters for an application. type App struct { - Name string `json:"name"` - Version string `json:"version"` - URI string `json:"uri"` - Envs []*config.Environment `json:"environments"` - Services []*config.Workload `json:"services"` - Jobs []*config.Workload `json:"jobs"` - Pipelines []*codepipeline.Pipeline `json:"pipelines"` - WkldDeployedtoEnvs map[string][]string `json:"-"` + Name string `json:"name"` + Version string `json:"version"` + URI string `json:"uri"` + PermissionsBoundary string `json:"permissionsBoundary"` + Envs []*config.Environment `json:"environments"` + Services []*config.Workload `json:"services"` + Jobs []*config.Workload `json:"jobs"` + Pipelines []*codepipeline.Pipeline `json:"pipelines"` + WkldDeployedtoEnvs map[string][]string `json:"-"` } // JSONString returns the stringified App struct with json format. @@ -53,8 +54,15 @@ func (a *App) HumanString() string { if deploy.LatestAppTemplateVersion != a.Version { availableVersion = color.Yellow.Sprintf("(latest available: %s)", deploy.LatestAppTemplateVersion) } + if a.URI == "" { + a.URI = "N/A" + } + if a.PermissionsBoundary == "" { + a.PermissionsBoundary = "N/A" + } fmt.Fprintf(writer, " %s\t%s %s\n", "Version", a.Version, availableVersion) fmt.Fprintf(writer, " %s\t%s\n", "URI", a.URI) + fmt.Fprintf(writer, " %s\t%s\n", "Permissions Boundary", a.PermissionsBoundary) fmt.Fprint(writer, color.Bold.Sprint("\nEnvironments\n\n")) writer.Flush() headers := []string{"Name", "AccountID", "Region"}