Skip to content

Commit

Permalink
Centralize envs with AWS Secrets Manager and AWS Parameter Store (#1)
Browse files Browse the repository at this point in the history
* building necessary cli commands for aws-env config

* fixing cli commands after testing

* fixing cli command for deployment and adding checking for string type

* fixing names of env files

* aws reigon global variable and constant

* more descriptive error message

* removing whitespace and dead code

* adding check for string type

* adding env file in utils

* error strings capatalized

* removing project constantsaddition to env file

* Making central WriteToEnvFile function

* centralizing constants and hardcoding bucket

* updating pull-config with new cent function
  • Loading branch information
codingwithsurya authored Sep 24, 2023
1 parent 18db82c commit 35a589b
Show file tree
Hide file tree
Showing 15 changed files with 519 additions and 1 deletion.
74 changes: 74 additions & 0 deletions cmd/backend/add_param/add-param.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package add_param

/*
$ dlp-cli backend add-param --name "YourParameterName" --value "YourParameterValue" --type "String"
*/

import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ssm"
"github.com/spf13/cobra"
"github.com/DSGT-DLP/Deep-Learning-Playground/cli/cmd/backend"
)

var (
paramName string
paramValue string
paramType string
)

var validParamTypes = map[string]bool{
"String": true,
"StringList": true,
"SecureString": true,
}

var addParamCmd = &cobra.Command{
Use: "add-param",
Short: "Add a new param to AWS Parameter Store",
Run: func(cmd *cobra.Command, args []string) {
if paramName == "" || paramValue == "" || paramType == "" {
fmt.Println("Error: You must provide a name, value, and type for the parameter.")
return
}

if !isValidParamType(paramType) {
fmt.Println("Error: Invalid parameter type. Accepted types are: String, StringList, SecureString.")
return
}

// Create an AWS session with the specified region
sess := session.Must(session.NewSession(&aws.Config{
Region: aws.String(backend.AwsRegion),
}))

svc := ssm.New(sess)
input := &ssm.PutParameterInput{
Name: aws.String(paramName),
Value: aws.String(paramValue),
Type: aws.String(paramType),
}

_, err := svc.PutParameter(input)
if err != nil {
fmt.Println("Error adding parameter:", err)
return
}

fmt.Println("Parameter added successfully.")
},
}

func isValidParamType(typ string) bool {
_, exists := validParamTypes[typ]
return exists
}

func init() {
addParamCmd.Flags().StringVar(&paramName, "name", "", "Name of the parameter")
addParamCmd.Flags().StringVar(&paramValue, "value", "", "Value of the parameter")
addParamCmd.Flags().StringVar(&paramType, "type", "", "Type of the parameter (String, StringList, SecureString)")
backend.BackendCmd.AddCommand(addParamCmd)
}
1 change: 1 addition & 0 deletions cmd/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
)

const BackendDir string = "./training"
const AwsRegion = "us-west-2"

// BackendCmd represents the backend command
var BackendCmd = &cobra.Command{
Expand Down
48 changes: 48 additions & 0 deletions cmd/backend/build_training_env/build-training-env-file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package build_training_env

/*
Sample Command:
$ dlp-cli build-training-env-file --secret "YourTrainingSecretName"
*/

import (
"log"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/secretsmanager"
"github.com/spf13/cobra"
"github.com/DSGT-DLP/Deep-Learning-Playground/cli/cmd/backend"
"github.com/DSGT-DLP/Deep-Learning-Playground/cli/utils" // For utils/
)

var secretNameTraining string // Name of the secret in AWS Secrets Manager

var buildTrainingEnvCmd = &cobra.Command{
Use: "build-training-env-file",
Short: "Build .env file for training/",
Run: func(cmd *cobra.Command, args []string) {
sess, err := session.NewSession(&aws.Config{Region: aws.String(backend.AwsRegion)})
if err != nil {
log.Fatal("error session: ", err)
}

smClient := secretsmanager.New(sess)
secretValue, err := smClient.GetSecretValue(&secretsmanager.GetSecretValueInput{SecretId: aws.String(secretNameTraining)})
if err != nil {
log.Fatal("error retrieving secret: ", err)
}

path := "./training"

// Adding secrets to the .env file
utils.WriteToEnvFile(secretNameTraining, *secretValue.SecretString, path)

// Hardcoding bucket name as a constant
utils.WriteToEnvFile("BUCKET_NAME", utils.DlpUploadBucket, path)
},
}

func init() {
buildTrainingEnvCmd.Flags().StringVar(&secretNameTraining, "secret", "", "Name of the secret in AWS Secrets Manager for training")
backend.BackendCmd.AddCommand(buildTrainingEnvCmd)
}
63 changes: 63 additions & 0 deletions cmd/backend/get_secret/get-secret.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package get_secret

/*
dlp-cli backend get-secret --name "YourSecretName"
*/

import (
"fmt"
"strings"

"github.com/DSGT-DLP/Deep-Learning-Playground/cli/cmd/backend"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/secretsmanager"
"github.com/spf13/cobra"
)

var secretName string

var getSecretCmd = &cobra.Command{
Use: "get-secret",
Short: "Retrieve a secret from AWS Secrets Manager",
Run: func(cmd *cobra.Command, args []string) {
if secretName == "" {
fmt.Println("Error: You must provide the name of the secret.")
return
}

sess, err := session.NewSession(&aws.Config{
Region: aws.String(backend.AwsRegion)},
)
if err != nil {
fmt.Println("Error creating AWS session:", err)
return
}

smClient := secretsmanager.New(sess)

input := &secretsmanager.GetSecretValueInput{
SecretId: aws.String(secretName),
}

result, err := smClient.GetSecretValue(input)
if err != nil {
// Check if the error is due to the secret not existing or a possible typo.
if strings.Contains(err.Error(), "secret not found") || strings.Contains(err.Error(), "secret name typo") {
fmt.Println("Error: The secret could not be retrieved. It may not exist or there could be a typo in the secret name.")
} else {
// Handle other error cases.
fmt.Println("Error retrieving secret:", err)
}
return
}


fmt.Printf("Secret [%s] successfully received: %s\n", secretName, *result.SecretString) //this validates that the secret was retrieved
},
}

func init() {
getSecretCmd.Flags().StringVar(&secretName, "name", "", "Name of the secret to retrieve")
backend.BackendCmd.AddCommand(getSecretCmd)
}
54 changes: 54 additions & 0 deletions cmd/backend/pull_config/pull-config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package pull_config

/*
$ go run main.go backend pull-config
*/

import (
"log"

"github.com/DSGT-DLP/Deep-Learning-Playground/cli/cmd/backend"
"github.com/DSGT-DLP/Deep-Learning-Playground/cli/utils" // For utils/
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ssm" // For Parameter Store
"github.com/spf13/cobra"
)

var pullConfigCmd = &cobra.Command{
Use: "pull-config",
Short: "Pulls values from parameter store/secrets manager and writes them to .env files",
Long: `This command pulls values from parameter store/secrets manager and writes them to .env files in /training and /frontend.`,
Args: cobra.ExactArgs(0),
Run: func(cmd *cobra.Command, args []string) {
sess, err := session.NewSession(&aws.Config{
Region: aws.String(backend.AwsRegion)},
)

if err != nil {
log.Fatal("Error creating AWS session: ", err)
}

ssmClient := ssm.New(sess)

parameterNames := []string{"parameter-name"}

for _, paramName := range parameterNames {
result, err := ssmClient.GetParameter(&ssm.GetParameterInput{
Name: aws.String(paramName),
WithDecryption: aws.Bool(true),
})

if err != nil {
log.Fatal("Error getting parameter: ", err)
}

utils.WriteToEnvFile(paramName, *result.Parameter.Value, backend.BackendDir)
utils.WriteToEnvFile(paramName, *result.Parameter.Value, "./frontend")
}
},
}

func init() {
backend.BackendCmd.AddCommand(pullConfigCmd)
}
52 changes: 52 additions & 0 deletions cmd/backend/remove_param/remove-param.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package remove_param

/*
$ dlp-cli backend remove-param --name "YourParameterName"
*/

import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ssm"
"github.com/spf13/cobra"
"github.com/DSGT-DLP/Deep-Learning-Playground/cli/cmd/backend"
)

var (
paramName string
)

var removeParamCmd = &cobra.Command{
Use: "remove-param",
Short: "Remove a parameter from AWS Parameter Store",
Run: func(cmd *cobra.Command, args []string) {
if paramName == "" {
fmt.Println("Error: You must provide the name of the parameter to remove.")
return
}

// Create an AWS session with the specified region
sess := session.Must(session.NewSession(&aws.Config{
Region: aws.String(backend.AwsRegion),
}))

svc := ssm.New(sess)
input := &ssm.DeleteParameterInput{
Name: aws.String(paramName),
}

_, err := svc.DeleteParameter(input)
if err != nil {
fmt.Println("Error removing parameter:", err)
return
}

fmt.Println("Parameter removed successfully.")
},
}

func init() {
removeParamCmd.Flags().StringVar(&paramName, "name", "", "Name of the parameter to remove")
backend.BackendCmd.AddCommand(removeParamCmd)
}
82 changes: 82 additions & 0 deletions cmd/backend/update_param/update-param.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package update_param

/*
$ dlp-cli backend update-param --name "ExistingParameterName" --value "NewParameterValue" --type "String" --overwrite true
*/

import (
"fmt"

"github.com/DSGT-DLP/Deep-Learning-Playground/cli/cmd/backend"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ssm"
"github.com/spf13/cobra"
)

var (
paramName string
paramValue string
paramType string
overwrite bool
)

func validateParamType(paramType string) bool {
// Define a list of valid parameter types
validTypes := []string{"String", "StringList", "SecureString"}

// Check if paramType is in the list of valid types
for _, t := range validTypes {
if paramType == t {
return true
}
}

return false
}

var updateParamCmd = &cobra.Command{
Use: "update-param",
Short: "Update an existing parameter value in AWS Parameter Store",
Run: func(cmd *cobra.Command, args []string) {
if paramName == "" || paramValue == "" || paramType == "" {
fmt.Println("Error: You must provide a name, value, and type for the parameter.")
return
}

// Validate the parameter type
if !validateParamType(paramType) {
fmt.Println("Error: Invalid parameter type. Please use one of: String, StringList, SecureString")
return
}

// Create an AWS session with the specified region
sess := session.Must(session.NewSession(&aws.Config{
Region: aws.String(backend.AwsRegion),
}))

svc := ssm.New(sess)
input := &ssm.PutParameterInput{
Name: aws.String(paramName),
Value: aws.String(paramValue),
Type: aws.String(paramType),
Overwrite: aws.Bool(overwrite),
}

_, err := svc.PutParameter(input)
if err != nil {
fmt.Println("Error updating parameter:", err)
return
}

fmt.Println("Parameter updated successfully.")
},
}

func init() {
updateParamCmd.Flags().StringVar(&paramName, "name", "", "Name of the parameter to update")
updateParamCmd.Flags().StringVar(&paramValue, "value", "", "New value for the parameter")
updateParamCmd.Flags().StringVar(&paramType, "type", "", "Type of the parameter (String, StringList, SecureString)")
updateParamCmd.Flags().BoolVar(&overwrite, "overwrite", true, "Whether to overwrite the parameter if it exists")
backend.BackendCmd.AddCommand(updateParamCmd)
}
Loading

0 comments on commit 35a589b

Please sign in to comment.