diff --git a/cmd/cluster/encryption/encryption.go b/cmd/cluster/encryption/encryption.go index 240a9dcf..df20dc45 100644 --- a/cmd/cluster/encryption/encryption.go +++ b/cmd/cluster/encryption/encryption.go @@ -66,7 +66,7 @@ var listCmk = &cobra.Command{ Output: os.Stdout, Format: formatter.NewCMKFormat(viper.GetString("output")), } - formatter.CMKWrite(cmkCtx, *resp.GetData().Spec.Get()) + formatter.CMKWrite(cmkCtx, *resp.Data) }, } diff --git a/cmd/cluster_test.go b/cmd/cluster_test.go index 09589df4..980e5af1 100644 --- a/cmd/cluster_test.go +++ b/cmd/cluster_test.go @@ -223,7 +223,7 @@ stunning-sole Dedicated 2.16.0.1-b7 ACTIVE 💚 AWS us-we Expect(err).ToNot(HaveOccurred()) err = loadJson("./test/fixtures/nodes.json", &responseNodes) Expect(err).ToNot(HaveOccurred()) - err = loadJson("./test/fixtures/cmk.json", &responseCMK) + err = loadJson("./test/fixtures/aws_cmk.json", &responseCMK) Expect(err).ToNot(HaveOccurred()) err = loadJson("./test/fixtures/one-cluster.json", &responseCluster) Expect(err).ToNot(HaveOccurred()) @@ -273,8 +273,8 @@ device-ip-gween device-ip-gween 152.165.26.42/32 Encryption at Rest -Provider Key Alias Security Principals CMK Status -AWS 0a80e409-e890-42fc-b209-bafb69931b2c arn:aws:kms:us-east-1:745846189716:key/db373c8d-1592-4c73-bfa3-420d05922933 ACTIVE +Provider Key Alias Last Rotated Security Principals CMK Status +AWS 0a80e409-e690-42fc-b209-baf969930b2c 2023-11-03T07:37:26.351Z arn:aws:kms:us-east-1:745846189716:key/41c64d5g-c97d-472c-889e-0d9f80d2c754 ACTIVE Nodes diff --git a/cmd/encryption_test.go b/cmd/encryption_test.go new file mode 100644 index 00000000..b7f41607 --- /dev/null +++ b/cmd/encryption_test.go @@ -0,0 +1,300 @@ +package cmd_test + +import ( + "fmt" + "net/http" + "os" + "os/exec" + "strings" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/onsi/gomega/gbytes" + "github.com/onsi/gomega/gexec" + "github.com/onsi/gomega/ghttp" + openapi "github.com/yugabyte/yugabytedb-managed-go-client-internal" +) + +var _ = Describe("Customer Managed Keys Test", func() { + + var ( + server *ghttp.Server + statusCode int + args []string + responseAccount openapi.AccountListResponse + responseProject openapi.AccountListResponse + responseListCluster openapi.ClusterListResponse + responseCMK openapi.CMKResponse + ) + + BeforeEach(func() { + args = os.Args + os.Args = []string{} + var err error + server, err = newGhttpServer(responseAccount, responseProject) + Expect(err).ToNot(HaveOccurred()) + os.Setenv("YBM_HOST", fmt.Sprintf("http://%s", server.Addr())) + os.Setenv("YBM_APIKEY", "test-token") + + statusCode = 200 + err = loadJson("./test/fixtures/list-clusters.json", &responseListCluster) + Expect(err).ToNot(HaveOccurred()) + server.AppendHandlers( + ghttp.CombineHandlers( + ghttp.VerifyRequest(http.MethodGet, "/api/public/v1/accounts/340af43a-8a7c-4659-9258-4876fd6a207b/projects/78d4459c-0f45-47a5-899a-45ddf43eba6e/clusters"), + ghttp.RespondWithJSONEncodedPtr(&statusCode, responseListCluster), + ), + ) + }) + + var _ = Describe("Describe Cluster CMK", func() { + + testCases := []struct { + jsonFilePath string + provider string + expected string + }{ + { + jsonFilePath: "./test/fixtures/aws_cmk.json", + provider: "AWS", + expected: `Provider Key Alias Last Rotated Security Principals CMK Status +AWS 0a80e409-e690-42fc-b209-baf969930b2c 2023-11-03T07:37:26.351Z arn:aws:kms:us-east-1:745846189716:key/41c64d5g-c97d-472c-889e-0d9f80d2c754 ACTIVE` + "\n", + }, + { + jsonFilePath: "./test/fixtures/azure_cmk.json", + provider: "AZURE", + expected: `Provider Key Alias Last Rotated Security Principals CMK Status +AZURE 8aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX5b 2023-11-03T07:37:26.351Z https://test-azure-gj.vault.azure.net/ ACTIVE` + "\n", + }, + { + jsonFilePath: "./test/fixtures/gcp_cmk.json", + provider: "GCP", + expected: `Provider Key Alias Last Rotated Security Principals CMK Status +GCP GCP-test-key 2023-11-03T07:37:26.351Z projects//locations/global/keyRings/GCP-test-key-ring/cryptoKeys/GCP-test-key ACTIVE` + "\n", + }, + } + + for _, tc := range testCases { + tc := tc + It(fmt.Sprintf("should successfully get CMK details for %s", tc.provider), func() { + err := loadJson(tc.jsonFilePath, &responseCMK) + Expect(err).ToNot(HaveOccurred()) + server.AppendHandlers( + ghttp.CombineHandlers( + ghttp.VerifyRequest(http.MethodGet, "/api/public/v1/accounts/340af43a-8a7c-4659-9258-4876fd6a207b/projects/78d4459c-0f45-47a5-899a-45ddf43eba6e/clusters/5f80730f-ba3f-4f7e-8c01-f8fa4c90dad8/cmks"), + ghttp.RespondWithJSONEncodedPtr(&statusCode, responseCMK), + ), + ) + cmd := exec.Command(compiledCLIPath, "cluster", "encryption", "list", "--cluster-name", "stunning-sole") + session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + Expect(err).NotTo(HaveOccurred()) + session.Wait(2) + o := string(session.Out.Contents()[:]) + Expect(o).Should(Equal(tc.expected)) + session.Kill() + }) + } + + It("should fail if no EAR configuration found for the cluster", func() { + responseCMK = *openapi.NewCMKResponse() + server.AppendHandlers( + ghttp.CombineHandlers( + ghttp.VerifyRequest(http.MethodGet, "/api/public/v1/accounts/340af43a-8a7c-4659-9258-4876fd6a207b/projects/78d4459c-0f45-47a5-899a-45ddf43eba6e/clusters/5f80730f-ba3f-4f7e-8c01-f8fa4c90dad8/cmks"), + ghttp.RespondWithJSONEncodedPtr(&statusCode, responseCMK), + ), + ) + cmd := exec.Command(compiledCLIPath, "cluster", "encryption", "list", "--cluster-name", "stunning-sole") + session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + Expect(err).NotTo(HaveOccurred()) + session.Wait(2) + Expect(session.Err).Should(gbytes.Say("No Encryption at rest configuration found for this cluster")) + session.Kill() + }) + }) + + var _ = Describe("Update cluster CMK", func() { + + testCases := []struct { + cloudProvider string + spec string + }{ + { + cloudProvider: "AWS", + spec: "cloud-provider=AWS,aws-secret-key=,aws-access-key=", + }, + { + cloudProvider: "AZURE", + spec: "cloud-provider=AZURE,azu-client-id=,azu-client-secret=,azu-tenant-id=,azu-key-name=,azu-key-vault-uri=", + }, + { + cloudProvider: "GCP", + spec: "cloud-provider=GCP,gcp-resource-id=projects//locations//keyRings//cryptoKeys/,gcp-service-account-path=creds.json", + }, + } + + BeforeEach(func() { + fileName := "creds.json" + os.WriteFile(fileName, []byte("{}"), 0644) + }) + + AfterEach(func() { + os.Remove("creds.json") + }) + + for _, tc := range testCases { + tc := tc + + It(fmt.Sprintf("should successfully update CMK for %s", tc.cloudProvider), func() { + err := loadJson(fmt.Sprintf("./test/fixtures/%s_cmk.json", strings.ToLower(tc.cloudProvider)), &responseCMK) + Expect(err).ToNot(HaveOccurred()) + server.AppendHandlers( + ghttp.CombineHandlers( + ghttp.VerifyRequest(http.MethodPut, "/api/public/v1/accounts/340af43a-8a7c-4659-9258-4876fd6a207b/projects/78d4459c-0f45-47a5-899a-45ddf43eba6e/clusters/5f80730f-ba3f-4f7e-8c01-f8fa4c90dad8/cmks"), + ghttp.RespondWithJSONEncodedPtr(&statusCode, responseCMK), + ), + ) + cmd := exec.Command(compiledCLIPath, "cluster", "encryption", "update", "--cluster-name", "stunning-sole", "--encryption-spec", tc.spec) + session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + Expect(err).NotTo(HaveOccurred()) + session.Wait(2) + Expect(session.Out).Should(gbytes.Say("Successfully updated encryption spec for cluster stunning-sole")) + session.Kill() + }) + } + + It("should fail if invalid cloud provider in encryption spec", func() { + cmd := exec.Command(compiledCLIPath, "cluster", "encryption", "update", "--cluster-name", "stunning-sole", "--encryption-spec", "cloud-provider=TEST_PROVIDER,access-key=,secret-key=") + session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + Expect(err).NotTo(HaveOccurred()) + session.Wait(2) + Expect(session.Err).Should(gbytes.Say("Incorrect format in CMK spec: invalid cloud-provider")) + session.Kill() + }) + + It("should fail if missing parameters in encryption spec", func() { + cmd := exec.Command(compiledCLIPath, "cluster", "encryption", "update", "--cluster-name", "stunning-sole", "--encryption-spec", "cloud-provider=AWS,aws-access-key=,secret-key=") + session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + Expect(err).NotTo(HaveOccurred()) + session.Wait(2) + Expect(session.Err).Should(gbytes.Say("Could not read AWS Secret key:")) + session.Kill() + }) + + It("should succeed if no EAR configuration found for the cluster", func() { + // In this case, a new EAR configuration would be added to this cluster + responseCMK = *openapi.NewCMKResponse() + server.AppendHandlers( + ghttp.CombineHandlers( + ghttp.VerifyRequest(http.MethodPut, "/api/public/v1/accounts/340af43a-8a7c-4659-9258-4876fd6a207b/projects/78d4459c-0f45-47a5-899a-45ddf43eba6e/clusters/5f80730f-ba3f-4f7e-8c01-f8fa4c90dad8/cmks"), + ghttp.RespondWithJSONEncodedPtr(&statusCode, responseCMK), + ), + ) + cmd := exec.Command(compiledCLIPath, "cluster", "encryption", "update", "--cluster-name", "stunning-sole", "--encryption-spec", "cloud-provider=AWS,aws-secret-key=,aws-access-key=") + session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + Expect(err).NotTo(HaveOccurred()) + session.Wait(2) + Expect(session.Out).Should(gbytes.Say("Successfully updated encryption spec for cluster stunning-sole")) + session.Kill() + }) + }) + + var _ = Describe("Update cluster CMK state", func() { + + testCases := []struct { + action string + expected string + }{ + { + action: "--enable", + expected: "Successfully ENABLED encryption spec status for cluster stunning-sole", + }, + { + action: "--disable", + expected: "Successfully DISABLED encryption spec status for cluster stunning-sole", + }, + } + + for _, tc := range testCases { + tc := tc + + It(fmt.Sprintf("should successfully %s the CMK state for azure", tc.action), func() { + + err := loadJson("./test/fixtures/aws_cmk.json", &responseCMK) + Expect(err).ToNot(HaveOccurred()) + server.AppendHandlers( + ghttp.CombineHandlers( + ghttp.VerifyRequest(http.MethodGet, "/api/public/v1/accounts/340af43a-8a7c-4659-9258-4876fd6a207b/projects/78d4459c-0f45-47a5-899a-45ddf43eba6e/clusters/5f80730f-ba3f-4f7e-8c01-f8fa4c90dad8/cmks"), + ghttp.RespondWithJSONEncodedPtr(&statusCode, responseCMK), + ), + ghttp.CombineHandlers( + ghttp.VerifyRequest(http.MethodPut, "/api/public/v1/accounts/340af43a-8a7c-4659-9258-4876fd6a207b/projects/78d4459c-0f45-47a5-899a-45ddf43eba6e/clusters/5f80730f-ba3f-4f7e-8c01-f8fa4c90dad8/cmks/41c64d5g-c97d-472c-889e-0d9f80d2c754/state"), + ghttp.RespondWithJSONEncodedPtr(&statusCode, responseCMK), + ), + ) + + cmd := exec.Command(compiledCLIPath, "cluster", "encryption", "update-state", "--cluster-name", "stunning-sole", tc.action) + session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + Expect(err).NotTo(HaveOccurred()) + session.Wait(2) + Expect(session.Out).Should(gbytes.Say(tc.expected)) + session.Kill() + }) + } + + It("should fail if no or both flags are specified", func() { + err := loadJson("./test/fixtures/aws_cmk.json", &responseCMK) + Expect(err).ToNot(HaveOccurred()) + server.AppendHandlers( + ghttp.CombineHandlers( + ghttp.VerifyRequest(http.MethodGet, "/api/public/v1/accounts/340af43a-8a7c-4659-9258-4876fd6a207b/projects/78d4459c-0f45-47a5-899a-45ddf43eba6e/clusters/5f80730f-ba3f-4f7e-8c01-f8fa4c90dad8/cmks"), + ghttp.RespondWithJSONEncodedPtr(&statusCode, responseCMK), + ), + ) + cmd := exec.Command(compiledCLIPath, "cluster", "encryption", "update-state", "--cluster-name", "stunning-sole") + session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + Expect(err).NotTo(HaveOccurred()) + session.Wait(2) + Expect(session.Err).Should(gbytes.Say("Please enter valid input. Specify either enable or disable flag.")) + + session.Kill() + }) + + It("should fail if both flags are specified", func() { + err := loadJson("./test/fixtures/aws_cmk.json", &responseCMK) + Expect(err).ToNot(HaveOccurred()) + server.AppendHandlers( + ghttp.CombineHandlers( + ghttp.VerifyRequest(http.MethodGet, "/api/public/v1/accounts/340af43a-8a7c-4659-9258-4876fd6a207b/projects/78d4459c-0f45-47a5-899a-45ddf43eba6e/clusters/5f80730f-ba3f-4f7e-8c01-f8fa4c90dad8/cmks"), + ghttp.RespondWithJSONEncodedPtr(&statusCode, responseCMK), + ), + ) + cmd := exec.Command(compiledCLIPath, "cluster", "encryption", "update-state", "--cluster-name", "stunning-sole", "--enable", "--disable") + session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + Expect(err).NotTo(HaveOccurred()) + session.Wait(2) + Expect(session.Err).Should(gbytes.Say("Please enter valid input. Specify either enable or disable flag.")) + session.Kill() + }) + + It("should fail if no EAR configuration found for the cluster", func() { + responseCMK = *openapi.NewCMKResponse() + server.AppendHandlers( + ghttp.CombineHandlers( + ghttp.VerifyRequest(http.MethodGet, "/api/public/v1/accounts/340af43a-8a7c-4659-9258-4876fd6a207b/projects/78d4459c-0f45-47a5-899a-45ddf43eba6e/clusters/5f80730f-ba3f-4f7e-8c01-f8fa4c90dad8/cmks"), + ghttp.RespondWithJSONEncodedPtr(&statusCode, responseCMK), + ), + ) + cmd := exec.Command(compiledCLIPath, "cluster", "encryption", "update-state", "--cluster-name", "stunning-sole", "--enable") + session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + Expect(err).NotTo(HaveOccurred()) + session.Wait(2) + Expect(session.Err).Should(gbytes.Say("No Encryption at rest configuration found for this cluster")) + session.Kill() + }) + }) + + AfterEach(func() { + os.Args = args + server.Close() + }) +}) diff --git a/cmd/test/fixtures/aws_cmk.json b/cmd/test/fixtures/aws_cmk.json new file mode 100644 index 00000000..3cb5547d --- /dev/null +++ b/cmd/test/fixtures/aws_cmk.json @@ -0,0 +1,27 @@ +{ + "data": { + "spec": { + "provider_type": "AWS", + "aws_cmk_spec": { + "access_key": "AKXXXXXXXXXXXXXXXXGC", + "secret_key": "l/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXOo", + "arn_list": [ + "arn:aws:kms:us-east-1:745846189716:key/41c64d5g-c97d-472c-889e-0d9f80d2c754" + ], + "alias_name": "0a80e409-e690-42fc-b209-baf969930b2c" + }, + "status": "ACTIVE", + "gcp_cmk_spec": null, + "azure_cmk_spec": null, + "is_enabled": false + }, + "info": { + "cmk_id": "41c64d5g-c97d-472c-889e-0d9f80d2c754", + "rotated_on": "2023-11-03T07:37:26.351Z", + "metadata": { + "created_on": "2023-11-03T07:37:26.351Z", + "updated_on": "2023-11-03T07:38:30.141Z" + } + } + } +} \ No newline at end of file diff --git a/cmd/test/fixtures/azure_cmk.json b/cmd/test/fixtures/azure_cmk.json new file mode 100644 index 00000000..95aef0fa --- /dev/null +++ b/cmd/test/fixtures/azure_cmk.json @@ -0,0 +1,28 @@ +{ + "data": { + "spec": { + "provider_type": "AZURE", + "aws_cmk_spec": null, + "status": "ACTIVE", + "gcp_cmk_spec": null, + "azure_cmk_spec": { + "client_id": "8aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX5b", + "client_secret": "bfXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXlZ", + "tenant_id": "81XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX83", + "key_vault_uri": "https://test-azure-gj.vault.azure.net/", + "key_name": "AZURE-test-key", + "key_algorithm": "RSA", + "key_size": 2048 + }, + "is_enabled": true + }, + "info": { + "cmk_id": "41c64d5f-c97d-472c-889e-0d9f80d2c754", + "rotated_on": "2023-11-03T07:37:26.351Z", + "metadata": { + "created_on": "2023-11-03T07:37:26.351Z", + "updated_on": "2023-11-03T07:38:30.141Z" + } + } + } +} \ No newline at end of file diff --git a/cmd/test/fixtures/cmk.json b/cmd/test/fixtures/cmk.json deleted file mode 100644 index 6d444d62..00000000 --- a/cmd/test/fixtures/cmk.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "data": { - "spec": { - "provider_type": "AWS", - "aws_cmk_spec": { - "access_key": "AKXXXXXXXXXXXXXXXXGC", - "secret_key": "l/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXOo", - "arn_list": [ - "arn:aws:kms:us-east-1:745846189716:key/db373c8d-1592-4c73-bfa3-420d05922933" - ], - "alias_name": "0a80e409-e890-42fc-b209-bafb69931b2c" - }, - "status": "ACTIVE", - "gcp_cmk_spec": null - } - } -} \ No newline at end of file diff --git a/cmd/test/fixtures/gcp_cmk.json b/cmd/test/fixtures/gcp_cmk.json new file mode 100644 index 00000000..c02a94c0 --- /dev/null +++ b/cmd/test/fixtures/gcp_cmk.json @@ -0,0 +1,38 @@ +{ + "data":{ + "spec":{ + "provider_type":"GCP", + "status":"ACTIVE", + "aws_cmk_spec":null, + "gcp_cmk_spec":{ + "location":"global", + "key_ring_name":"GCP-test-key-ring", + "key_name":"GCP-test-key", + "protection_level":"software", + "gcp_service_account":{ + "type":"service_account", + "project_id":"", + "private_key_id":"", + "private_key":"", + "client_email":"", + "client_id":"", + "token_uri":"", + "auth_provider_x509_cert_url":"", + "client_x509_cert_url":"", + "universe_domain":"googleapis.com" + } + }, + "azure_cmk_spec":null, + "is_enabled":false + }, + "info":{ + "cmk_id":"41c64d5g-c97d-472c-889e-0d9f80d2c754", + "rotated_on":"2023-11-03T07:37:26.351Z", + "metadata":{ + "created_on":"2023-11-03T07:37:26.351Z", + "updated_on":"2023-11-03T07:38:30.141Z" + } + } + } + } \ No newline at end of file diff --git a/internal/cluster/cluster.go b/internal/cluster/cluster.go index f0e86be2..4ee49052 100644 --- a/internal/cluster/cluster.go +++ b/internal/cluster/cluster.go @@ -32,7 +32,7 @@ type FullCluster struct { //Nodes of the cluster Nodes []ybmclient.NodeData //CMK of the cluster - CMK []ybmclient.CMKSpec + CMK []ybmclient.CMKData //Helpful to filter by provider Providers []string } @@ -65,7 +65,7 @@ func (f *FullCluster) SetCMK(authApi ybmAuthClient.AuthApiClient) { if _, ok := resp.GetDataOk(); ok { // Make an array here with a single element. // In the future, we will support CMK per region. - f.CMK = append(f.CMK, *resp.GetData().Spec.Get()) + f.CMK = append(f.CMK, *resp.Data) } } diff --git a/internal/formatter/clusters_full.go b/internal/formatter/clusters_full.go index 1d3fc6ec..150a3958 100644 --- a/internal/formatter/clusters_full.go +++ b/internal/formatter/clusters_full.go @@ -37,7 +37,7 @@ const ( defaultVPCListingCluster = "table {{.Name}}\t{{.State}}\t{{.Provider}}\t{{.Regions}}\t{{.CIDR}}\t{{.Peerings}}" defaultDefaultFullClusterRegion = "table {{.Region}}\t{{.NumNode}}\t{{.NumCores}}\t{{.MemoryGb}}\t{{.DiskSizeGb}}\t{{.VpcName}}" defaultFullClusterNalListing = "table {{.Name}}\t{{.Desc}}\t{{.AllowedList}}" - defaultFullClusterCMK = "table {{.Provider}}\t{{.KeyAlias}}\t{{.SecurityPrincipals}}\t{{.CMKStatus}}" + defaultFullClusterCMK = "table {{.Provider}}\t{{.KeyAlias}}\t{{.LastRotated}}\t{{.SecurityPrincipals}}\t{{.CMKStatus}}" defaultFullClusterEndpoints = "table {{.Region}}\t{{.Accessibility}}\t{{.State}}\t{{.Host}}" faultToleranceHeader = "Fault Tolerance" dataDistributionHeader = "Data Distribution" diff --git a/internal/formatter/encryption.go b/internal/formatter/encryption.go index dd173ecf..ce749225 100644 --- a/internal/formatter/encryption.go +++ b/internal/formatter/encryption.go @@ -24,15 +24,16 @@ import ( ) const ( - keyAliasHeader = "Key Alias" - cmkStatusHeader = "CMK Status" - defaultCmkFormat = "table {{.Provider}}\t{{.KeyAlias}}\t{{.SecurityPrincipals}}\t{{.CMKStatus}}" + keyAliasHeader = "Key Alias" + cmkStatusHeader = "CMK Status" + lastRotatedHeader = "Last Rotated" + defaultCmkFormat = "table {{.Provider}}\t{{.KeyAlias}}\t{{.LastRotated}}\t{{.SecurityPrincipals}}\t{{.CMKStatus}}" ) type CMKContext struct { HeaderContext Context - c ybmclient.CMKSpec + c ybmclient.CMKData } func NewCMKContext() *CMKContext { @@ -42,6 +43,7 @@ func NewCMKContext() *CMKContext { "KeyAlias": keyAliasHeader, "SecurityPrincipals": securityPrincipalsHeader, "CMKStatus": cmkStatusHeader, + "LastRotated": lastRotatedHeader, } return &cmkContext } @@ -56,9 +58,9 @@ func NewCMKFormat(source string) Format { } } -func CMKWrite(ctx Context, cmkSpec ybmclient.CMKSpec) error { +func CMKWrite(ctx Context, cmkData ybmclient.CMKData) error { render := func(format func(subContext SubContext) error) error { - err := format(&CMKContext{c: cmkSpec}) + err := format(&CMKContext{c: cmkData}) if err != nil { logrus.Debug(err) return err @@ -69,39 +71,44 @@ func CMKWrite(ctx Context, cmkSpec ybmclient.CMKSpec) error { } func (c *CMKContext) Provider() ybmclient.CMKProviderEnum { - return c.c.ProviderType + return c.c.Spec.Get().ProviderType +} + +func (c *CMKContext) LastRotated() string { + return *c.c.Info.RotatedOn.Get() } func (c *CMKContext) CMKStatus() ybmclient.CMKStatusEnum { - return *c.c.Status.Get() + return *c.c.GetSpec().Status.Get() } func (c *CMKContext) KeyAlias() string { - if c.c.GcpCmkSpec.Get().GetKeyName() != "" { - return c.c.GcpCmkSpec.Get().GetKeyName() - } else if c.c.AzureCmkSpec.Get().GetKeyName() != "" { - return c.c.AzureCmkSpec.Get().GetKeyName() + if c.c.GetSpec().GcpCmkSpec.Get().GetKeyName() != "" { + return c.c.GetSpec().GcpCmkSpec.Get().GetKeyName() + } else if c.c.GetSpec().AzureCmkSpec.Get().GetKeyName() != "" { + return c.c.GetSpec().AzureCmkSpec.Get().GetClientId() + } else { + return c.c.GetSpec().AwsCmkSpec.Get().GetAliasName() } - return c.c.AwsCmkSpec.Get().GetAliasName() } func (c *CMKContext) ResourceId() string { // Resource id: projects/{PROJECT_ID}/locations/{LOCATION}/keyRings/{KEY_RING_NAME}/cryptoKeys/{KEY_NAME} - keyName := c.c.GcpCmkSpec.Get().GetKeyName() - location := c.c.GcpCmkSpec.Get().GetLocation() - keyRingName := c.c.GcpCmkSpec.Get().GetKeyRingName() - projectId := c.c.GcpCmkSpec.Get().GetGcpServiceAccount().ProjectId + keyName := c.c.GetSpec().GcpCmkSpec.Get().GetKeyName() + location := c.c.GetSpec().GcpCmkSpec.Get().GetLocation() + keyRingName := c.c.GetSpec().GcpCmkSpec.Get().GetKeyRingName() + projectId := c.c.GetSpec().GcpCmkSpec.Get().GetGcpServiceAccount().ProjectId resourceId := "projects/" + projectId + "/locations/" + location + "/keyRings/" + keyRingName + "/cryptoKeys/" + keyName return resourceId } func (c *CMKContext) SecurityPrincipals() string { - if c.c.GcpCmkSpec.Get().GetKeyName() != "" { + if c.c.GetSpec().GcpCmkSpec.Get().GetKeyName() != "" { return c.ResourceId() - } else if c.c.AzureCmkSpec.Get().GetKeyName() != "" { - return c.c.AzureCmkSpec.Get().GetKeyVaultUri() + } else if c.c.GetSpec().AzureCmkSpec.Get().GetKeyName() != "" { + return c.c.GetSpec().AzureCmkSpec.Get().GetKeyVaultUri() } - return strings.Join(c.c.AwsCmkSpec.Get().GetArnList(), ", ") + return strings.Join(c.c.GetSpec().AwsCmkSpec.Get().GetArnList(), ", ") } func (c *CMKContext) MarshalJSON() ([]byte, error) {