Skip to content

Commit

Permalink
[BACKPORT 2024.1][PLAT-14805]Support adding EAR configs
Browse files Browse the repository at this point in the history
Summary:
Command format: `./yba ear <provider-type (aws/azure/gcp/hcv)> create -n <name> [flags]`

AWS:
```
./yba ear aws create
Create an AWS encryption at rest configuration in YugabyteDB Anywhere

Usage:
  yba ear aws create [flags]

Aliases:
  create, add

Flags:
      --access-key-id string          AWS Access Key ID. Required for non IAM role based configurations. Can also be set using environment variable AWS_ACCESS_KEY_ID.
      --secret-access-key string      AWS Secret Access Key. Required for non IAM role based configurations. Can also be set using environment variable AWS_SECRET_ACCESS_KEY.
      --region string                 AWS region where the customer master key is located. Can also be set using environment variable AWS_REGION
      --use-iam-instance-profile      [Optional] Use IAM Role from the YugabyteDB Anywhere Host. EAR creation will fail on insufficient permissions on the host. (default false)
      --cmk-id string                 [Optional] Customer Master Key ID. If an identifier is not entered, a CMK ID will be auto-generated.
      --endpoint string               [Optional] AWS KMS Endpoint.
      --cmk-policy-file-path string   [Optional] AWS KMS Customer Master Key Policy file path. Custom policy file is not needed when Customer Master Key ID is specified. Allowed file type is json.
  -h, --help                          help for create

Global Flags:
  -a, --apiToken string    YugabyteDB Anywhere api token.
      --config string      Config file, defaults to $HOME/.yba-cli.yaml
      --debug              Use debug mode, same as --logLevel debug.
      --disable-color      Disable colors in output. (default false)
  -H, --host string        YugabyteDB Anywhere Host (default "http://localhost:9000")
  -l, --logLevel string    Select the desired log level format. Allowed values: debug, info, warn, error, fatal. (default "info")
  -n, --name string        [Optional] The name of the configuration for the action. Required for create, delete, describe, update.
  -o, --output string      Select the desired output format. Allowed values: table, json, pretty. (default "table")
      --timeout duration   Wait command timeout, example: 5m, 1h. (default 168h0m0s)
      --wait               Wait until the task is completed, otherwise it will exit immediately. (default true)
```

Azure:
```
Create an Azure encryption at rest configuration in YugabyteDB Anywhere

Usage:
  yba ear azure create [flags]

Aliases:
  create, add

Flags:
      --client-id string       Azure Client ID. Can also be set using environment variable AZURE_CLIENT_ID.
      --tenant-id string       Azure Tenant ID. Can also be set using environment variable AZURE_TENANT_ID.
      --client-secret string   Azure Secret Access Key. Required for Non Managed Identity based configurations. Can also be set using environment variable AZURE_CLIENT_SECRET.
      --use-managed-identity   [Optional] Use Azure Managed Identity from the YugabyteDB Anywhere Host. EAR creation will fail on insufficient permissions on the host. (default false)
      --vault-url string       [Required] Azure Vault URL.
      --key-name string        [Required] Azure Key Name.If master key with same name already exists then it will be used, else a new one will be created automatically.
      --key-algorithm string   [Optional] Azure Key Algorithm. Allowed values (case sensitive): RSA (default "RSA")
      --key-size int           [Optional] Azure Key Size. Allowed values per algorithm: RSA(Default:2048, 3072, 4096)
  -h, --help                   help for create

Global Flags:
  -a, --apiToken string    YugabyteDB Anywhere api token.
      --config string      Config file, defaults to $HOME/.yba-cli.yaml
      --debug              Use debug mode, same as --logLevel debug.
      --disable-color      Disable colors in output. (default false)
  -H, --host string        YugabyteDB Anywhere Host (default "http://localhost:9000")
  -l, --logLevel string    Select the desired log level format. Allowed values: debug, info, warn, error, fatal. (default "info")
  -n, --name string        [Optional] The name of the configuration for the action. Required for create, delete, describe, update.
  -o, --output string      Select the desired output format. Allowed values: table, json, pretty. (default "table")
      --timeout duration   Wait command timeout, example: 5m, 1h. (default 168h0m0s)
      --wait               Wait until the task is completed, otherwise it will exit immediately. (default true)
```

GCP:
```
./yba ear gcp  create
Create a GCP encryption at rest configuration in YugabyteDB Anywhere

Usage:
  yba ear gcp create [flags]

Aliases:
  create, add

Flags:
      --credentials-file-path string   GCP Credentials File Path. Can also be set using environment variable GOOGLE_APPLICATION_CREDENTIALS.
      --location string                [Optional] The geographical region where the Cloud KMS resource is stored and accessed. (default "global")
      --key-ring-name string           [Required] Name of the key ring. If key ring with same name already exists then it will be used, else a new one will be created automatically.
      --crypto-key-name string         [Required] Name of the cryptographic key that will be used for encrypting and decrypting universe key. If crypto key with same name already exists then it will be used, else a new one will be created automatically.
      --protection-level string        [Optional] The protection level to use for this key. Allowed values (case sensitive): SOFTWARE and HSM. (default "HSM")
      --endpoint string                [Optional] GCP KMS Endpoint.
  -h, --help                           help for create

Global Flags:
  -a, --apiToken string    YugabyteDB Anywhere api token.
      --config string      Config file, defaults to $HOME/.yba-cli.yaml
      --debug              Use debug mode, same as --logLevel debug.
      --disable-color      Disable colors in output. (default false)
  -H, --host string        YugabyteDB Anywhere Host (default "http://localhost:9000")
  -l, --logLevel string    Select the desired log level format. Allowed values: debug, info, warn, error, fatal. (default "info")
  -n, --name string        [Optional] The name of the configuration for the action. Required for create, delete, describe, update.
  -o, --output string      Select the desired output format. Allowed values: table, json, pretty. (default "table")
      --timeout duration   Wait command timeout, example: 5m, 1h. (default 168h0m0s)
      --wait               Wait until the task is completed, otherwise it will exit immediately. (default true)
```

HCV:
```
Create a Hashicorp Vault encryption at rest configuration in YugabyteDB Anywhere

Usage:
  yba ear hashicorp create [flags]

Aliases:
  create, add

Flags:
      --vault-address string    Hashicorp Vault address. Can also be set using environment variable VAULT_ADDR
      --role-id string          [Optional] Hashicorp Vault AppRole ID.
      --secret-id string        [Optional] Hashicorp Vault AppRole Secret ID.
      --auth-namespace string   [Optional] Hashicorp Vault AppRole Auth Namespace.
      --token string            [Optional] Hashicorp Vault Token. Required if AppRole credentials are not provided. Can also be set using environment variable VAULT_TOKEN
      --secret-engine string    [Optional] Hashicorp Vault Secret Engine. Allowed values: transit. (default "transit")
      --key-name string         [Optional] Hashicorp Vault key name. If key with same name already exists then it will be used, else a new one will be created automatically. (default "key_yugabyte")
      --mount-path string       [Optional] Hashicorp Vault mount path. (default "transit/")
  -h, --help                    help for create

Global Flags:
  -a, --apiToken string    YugabyteDB Anywhere api token.
      --config string      Config file, defaults to $HOME/.yba-cli.yaml
      --debug              Use debug mode, same as --logLevel debug.
      --disable-color      Disable colors in output. (default false)
  -H, --host string        YugabyteDB Anywhere Host (default "http://localhost:9000")
  -l, --logLevel string    Select the desired log level format. Allowed values: debug, info, warn, error, fatal. (default "info")
  -n, --name string        [Optional] The name of the configuration for the action. Required for create, delete, describe, update.
  -o, --output string      Select the desired output format. Allowed values: table, json, pretty. (default "table")
      --timeout duration   Wait command timeout, example: 5m, 1h. (default 168h0m0s)
      --wait               Wait until the task is completed, otherwise it will exit immediately. (default true)
```

Original commit: 38d8ae8 / D37728

Test Plan:
`./yba ear hashicorp add -n dkumar-cli --token <token>  --vault-address <>`

`./yba ear hcv create -n dkumar-cli-approle --role-id <> --secret-id <> --vault-address <>`

`./yba ear aws add -n dkumar-aws-cli --access-key-id <> --secret-access-key <>  --cmk-id <>`

`./yba ear aws add -n dkumar-aws-cli --access-key-id <>--secret-access-key <>  --cmk-policy-file-path policy.json `

` ./yba ear gcp add -n dkumar-cli-gcp --credentials-file-path gce.json --key-ring-name <> --crypto-key-name <>`

`./yba ear azu create -n dkumar-cli-az --vault-url <> --key-name <>--client-id <> --tenant-id <> --client-secret <>`

Reviewers: sneelakantan, skurapati

Reviewed By: skurapati

Subscribers: yugaware

Differential Revision: https://phorge.dev.yugabyte.com/D37769
  • Loading branch information
Deepti-yb committed Sep 5, 2024
1 parent 9f8c943 commit 2bf6354
Show file tree
Hide file tree
Showing 29 changed files with 1,285 additions and 70 deletions.
4 changes: 2 additions & 2 deletions managed/yba-cli/NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ The following subcomponents are used:
## github.com/aws/aws-sdk-go

* Name: github.com/aws/aws-sdk-go
* Version: v1.45.24
* License: [Apache-2.0](https://github.com/aws/aws-sdk-go/blob/v1.45.24/LICENSE.txt)
* Version: v1.55.5
* License: [Apache-2.0](https://github.com/aws/aws-sdk-go/blob/v1.55.5/LICENSE.txt)


## github.com/aws/aws-sdk-go/internal/sync/singleflight
Expand Down
2 changes: 1 addition & 1 deletion managed/yba-cli/cmd/ear/aws/aws_ear.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ var AWSEARCmd = &cobra.Command{
func init() {
AWSEARCmd.Flags().SortFlags = false

// AWSEARCmd.AddCommand(createAWSEARCmd)
AWSEARCmd.AddCommand(createAWSEARCmd)
// AWSEARCmd.AddCommand(updateAWSEARCmd)
AWSEARCmd.AddCommand(listAWSEARCmd)
AWSEARCmd.AddCommand(describeAWSEARCmd)
Expand Down
178 changes: 178 additions & 0 deletions managed/yba-cli/cmd/ear/aws/create_ear.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/*
* Copyright (c) YugaByte, Inc.
*/

package aws

import (
"fmt"
"strings"

"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/yugabyte/yugabyte-db/managed/yba-cli/cmd/ear/earutil"
"github.com/yugabyte/yugabyte-db/managed/yba-cli/cmd/util"
ybaAuthClient "github.com/yugabyte/yugabyte-db/managed/yba-cli/internal/client"
"github.com/yugabyte/yugabyte-db/managed/yba-cli/internal/formatter"
)

// createAWSEARCmd represents the ear command
var createAWSEARCmd = &cobra.Command{
Use: "create",
Aliases: []string{"add"},
Short: "Create a YugabyteDB Anywhere AWS encryption at rest configuration",
Long: "Create an AWS encryption at rest configuration in YugabyteDB Anywhere",
PreRun: func(cmd *cobra.Command, args []string) {
configNameFlag, err := cmd.Flags().GetString("name")
if err != nil {
logrus.Fatalf(formatter.Colorize(err.Error()+"\n", formatter.RedColor))
}
if len(strings.TrimSpace(configNameFlag)) == 0 {
cmd.Help()
logrus.Fatalln(
formatter.Colorize(
"No encryption at rest config name found to create\n",
formatter.RedColor))
}
isIAM, err := cmd.Flags().GetBool("use-iam-instance-profile")
if err != nil {
logrus.Fatalf(formatter.Colorize(err.Error()+"\n", formatter.RedColor))
}

accessKeyID, err := cmd.Flags().GetString("access-key-id")
if err != nil {
logrus.Fatalf(formatter.Colorize(err.Error()+"\n", formatter.RedColor))
}
if isIAM && len(accessKeyID) > 0 {
cmd.Help()
logrus.Fatalln(
formatter.Colorize("Cannot set both credentials and use-iam-instance-profile"+
"\n", formatter.RedColor))
}
},
Run: func(cmd *cobra.Command, args []string) {
authAPI := ybaAuthClient.NewAuthAPIClientAndCustomer()

requestBody := make(map[string]interface{})

configName, err := cmd.Flags().GetString("name")
if err != nil {
logrus.Fatalf(formatter.Colorize(err.Error()+"\n", formatter.RedColor))
}
requestBody["name"] = configName

isIAM, err := cmd.Flags().GetBool("use-iam-instance-profile")
if err != nil {
logrus.Fatalf(formatter.Colorize(err.Error()+"\n", formatter.RedColor))
}
if !isIAM {
accessKeyID, err := cmd.Flags().GetString("access-key-id")
if err != nil {
logrus.Fatalf(formatter.Colorize(err.Error()+"\n", formatter.RedColor))
}
secretAccessKey, err := cmd.Flags().GetString("secret-access-key")
if err != nil {
logrus.Fatalf(formatter.Colorize(err.Error()+"\n", formatter.RedColor))
}
if len(accessKeyID) == 0 && len(secretAccessKey) == 0 {
awsCreds, err := util.AwsCredentialsFromEnv()
if err != nil {
logrus.Fatalf(formatter.Colorize(err.Error()+"\n", formatter.RedColor))
}
accessKeyID = awsCreds.AccessKeyID
secretAccessKey = awsCreds.SecretAccessKey
}
requestBody[util.AWSAccessKeyEnv] = accessKeyID
requestBody[util.AWSSecretAccessKeyEnv] = secretAccessKey
}

region, err := cmd.Flags().GetString("region")
if err != nil {
logrus.Fatalf(formatter.Colorize(err.Error()+"\n", formatter.RedColor))
}
if len(strings.TrimSpace(region)) == 0 {
region, err = util.AWSRegionFromEnv()
if err != nil {
logrus.Fatalf(formatter.Colorize(err.Error()+"\n", formatter.RedColor))
}
}
requestBody[util.AWSRegionEnv] = region

endpoint, err := cmd.Flags().GetString("endpoint")
if err != nil {
logrus.Fatalf(formatter.Colorize(err.Error()+"\n", formatter.RedColor))
}
if len(strings.TrimSpace(endpoint)) != 0 {
requestBody[util.AWSEndpointEnv] = endpoint
}

cmkID, err := cmd.Flags().GetString("cmk-id")
if err != nil {
logrus.Fatalf(formatter.Colorize(err.Error()+"\n", formatter.RedColor))
}
if len(strings.TrimSpace(cmkID)) != 0 {
requestBody[util.AWSCMKIDField] = cmkID
} else {
cmkPolicyFile, err := cmd.Flags().GetString("cmk-policy-file-path")
if err != nil {
logrus.Fatalf(formatter.Colorize(err.Error()+"\n", formatter.RedColor))
}
if len(strings.TrimSpace(cmkPolicyFile)) != 0 {
cmkPolicy, err := util.ReadFileToString(cmkPolicyFile)
if err != nil {
logrus.Fatalf(formatter.Colorize(err.Error()+"\n", formatter.RedColor))
}
requestBody[util.AWSCMKPolicyField] = cmkPolicy
}
}

rCreate, response, err := authAPI.CreateKMSConfig(util.AWSEARType).
KMSConfig(requestBody).Execute()
if err != nil {
errMessage := util.ErrorFromHTTPResponse(response, err, "EAR: AWS", "Create")
logrus.Fatalf(formatter.Colorize(errMessage.Error()+"\n", formatter.RedColor))
}

configUUID := rCreate.GetResourceUUID()
taskUUID := rCreate.GetTaskUUID()

earutil.WaitForCreateEARTask(authAPI,
configName, configUUID, util.AWSEARType, taskUUID)

},
}

func init() {
createAWSEARCmd.Flags().SortFlags = false

createAWSEARCmd.Flags().String("access-key-id", "",
fmt.Sprintf("AWS Access Key ID. %s "+
"Can also be set using environment variable %s.",
formatter.Colorize("Required for non IAM role based configurations.",
formatter.GreenColor),
util.AWSAccessKeyEnv))
createAWSEARCmd.Flags().String("secret-access-key", "",
fmt.Sprintf("AWS Secret Access Key. %s "+
"Can also be set using environment variable %s.",
formatter.Colorize("Required for non IAM role based configurations.",
formatter.GreenColor),
util.AWSSecretAccessKeyEnv))
createAWSEARCmd.MarkFlagsRequiredTogether("access-key-id", "secret-access-key")
createAWSEARCmd.Flags().String("region", "",
fmt.Sprintf("AWS region where the customer master key is located. "+
"Can also be set using environment variable %s",
util.AWSRegionEnv))
createAWSEARCmd.Flags().Bool("use-iam-instance-profile", false,
"[Optional] Use IAM Role from the YugabyteDB Anywhere Host. EAR "+
"creation will fail on insufficient permissions on the host. (default false)")

createAWSEARCmd.Flags().String("cmk-id", "",
"[Optional] Customer Master Key ID. "+
"If an identifier is not entered, a CMK ID will be auto-generated.")
createAWSEARCmd.Flags().String("endpoint", "",
"[Optional] AWS KMS Endpoint.")
createAWSEARCmd.Flags().String("cmk-policy-file-path", "",
"[Optional] AWS KMS Customer Master Key Policy file path. "+
"Custom policy file is not needed when Customer Master Key ID is specified. "+
"Allowed file type is json.")
}
2 changes: 1 addition & 1 deletion managed/yba-cli/cmd/ear/azu/azu_ear.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var AzureEARCmd = &cobra.Command{
func init() {
AzureEARCmd.Flags().SortFlags = false

// AzureEARCmd.AddCommand(createAzureEARCmd)
AzureEARCmd.AddCommand(createAzureEARCmd)
// AzureEARCmd.AddCommand(updateAzureEARCmd)
AzureEARCmd.AddCommand(listAzureEARCmd)
AzureEARCmd.AddCommand(describeAzureEARCmd)
Expand Down
Loading

0 comments on commit 2bf6354

Please sign in to comment.