diff --git a/.travis.yml b/.travis.yml index 8d43ecc7..3d7e901c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,7 @@ dist: trusty language: go - +install: +- curl -fSL --retry 5 https://github.com/gobuffalo/packr/releases/download/v1.13.1/packr_1.13.1_linux_amd64.tar.gz | sudo tar zx -C /usr/bin/ jobs: include: - stage: test diff --git a/Makefile b/Makefile index c66dc3e1..849111c7 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ build: packr @CGO_ENABLED=0 GOOS=linux go build -o terraform-provider-bless -test: +test: packr @TF_ACC=yes go test -cover -v ./... packr: diff --git a/bless_lambda/bless_deploy.cfg.tpl b/bless_lambda/bless_deploy.cfg.tpl index 40390692..3bb7550c 100644 --- a/bless_lambda/bless_deploy.cfg.tpl +++ b/bless_lambda/bless_deploy.cfg.tpl @@ -3,8 +3,8 @@ certificate_validity_after_seconds = 3600 certificate_validity_before_seconds = 3600 entropy_minimum_bits = 2048 random_seed_bytes = 256 -logging_level = DEBUG -username_validation = email +logging_level = {{ .LoggingLevel }} +username_validation = {{ .UsernameValidation }} [Bless CA] default_password = {{ .EncryptedPassword }} @@ -14,6 +14,6 @@ ca_private_key = {{ .EncryptedPrivateKey }} use_kmsauth = True kmsauth_key_id = {{ .KMSAuthKeyID }} kmsauth_serviceid = {{ .Name }} -kmsauth_remote_usernames_allowed = * -kmsauth_validate_remote_usernames_against_iam_groups = True -kmsauth_iam_group_name_format = ssh-{} +kmsauth_remote_usernames_allowed = {{ .KMSAuthRemoteUsernamesAllowed }} +kmsauth_validate_remote_usernames_against_iam_groups = {{ pythonBool .KMSAuthValidateRemoteUsernameAgainstIAMGroups }} +kmsauth_iam_group_name_format = {{ .KMSAuthIAMGroupNameFormat }} diff --git a/pkg/provider/data_lambda.go b/pkg/provider/data_lambda.go index 1d14138d..f11ced53 100644 --- a/pkg/provider/data_lambda.go +++ b/pkg/provider/data_lambda.go @@ -7,9 +7,9 @@ import ( "io" "io/ioutil" "os" - "sort" - "path/filepath" "path" + "path/filepath" + "sort" "github.com/chanzuckerberg/terraform-provider-bless/pkg/util" "github.com/gobuffalo/packr" @@ -18,8 +18,13 @@ import ( ) const ( - schemaServiceName = "service_name" - schemaKMSAuthKeyID = "kmsauth_key_id" + schemaServiceName = "service_name" + schemaLoggingLevel = "logging_level" + schemaUsernameValidation = "username_validation" + schemaKMSAuthKeyID = "kmsauth_key_id" + schemaKMSAuthRemoteUsernamesAllowed = "kmsauth_remote_usernames_allowed" + schemaKMSAuthValidateRemoteUsernameAgainstIAMGroups = "kmsauth_validate_remote_user" + schemaKMSAuthIAMGroupNameFormat = "kmsauth_iam_group_name_format" // SchemaOutputBase64Sha256 is the base64 encoded sha256 of bless.zip contents SchemaOutputBase64Sha256 = "output_base64sha256" @@ -64,6 +69,41 @@ func Lambda() *schema.Resource { Description: "Path where the bless zip archive will be written", ForceNew: true, }, + schemaLoggingLevel: &schema.Schema{ + Type: schema.TypeString, + Default: "INFO", + Optional: true, + ForceNew: true, + Description: "Bless lambda logging level", + }, + schemaUsernameValidation: &schema.Schema{ + Type: schema.TypeString, + Default: "email", + Optional: true, + ForceNew: true, + Description: "Bless lambda default username validation", + }, + schemaKMSAuthRemoteUsernamesAllowed: &schema.Schema{ + Type: schema.TypeString, + Default: "*", + Optional: true, + ForceNew: true, + Description: "The remote usernames allowed. \"*\" indicates any", + }, + schemaKMSAuthValidateRemoteUsernameAgainstIAMGroups: &schema.Schema{ + Type: schema.TypeBool, + Default: true, + Optional: true, + ForceNew: true, + Description: "If bless should validate a remote username against an IAM group membership", + }, + schemaKMSAuthIAMGroupNameFormat: &schema.Schema{ + Type: schema.TypeString, + Default: "ssh-{}", + Optional: true, + ForceNew: true, + Description: "The format of IAM Group Name used to validate membership.", + }, // computed SchemaOutputBase64Sha256: &schema.Schema{ @@ -78,14 +118,24 @@ func Lambda() *schema.Resource { // type blessConfig struct { + // Name is the name of this service + Name string + // LoggingLevel + LoggingLevel string + // UsernameValidation tells bless how to validate usernames + UsernameValidation string // EncryptedPassword is the kms encrypted password for the CA private key EncryptedPassword string // EncryptedPrivateKey is a password encrypted CA private key EncryptedPrivateKey string - // Name is the name of this service - Name string - // KMSAuthKeyID is the kmsauth key ID + // KMSAuthKeyID the kmsauth kms key id KMSAuthKeyID string + // KMSAuthRemoteUsernamesAllowed the remote usernames allowed + KMSAuthRemoteUsernamesAllowed string + // KMSAuthValidateRemoteUsernameAgainstIAMGroups if kmsauth should validate the remote username against an IAM group membership + KMSAuthValidateRemoteUsernameAgainstIAMGroups bool + // KMSAuthIAMGroupNameFormat a pattern to fetch iam groups typically ssh-{} where {} will be replaced with the remote-username + KMSAuthIAMGroupNameFormat string } // resourceLambda is a namespace @@ -123,16 +173,33 @@ func (l *resourceLambda) getBlessConfig(d *schema.ResourceData) (io.Reader, erro if err != nil { return nil, errors.Wrap(err, "Could not read bless_deploy.cfg.tpl") } - t, err := template.New("config").Parse(string(tplBytes)) + t, err := template. + New("config"). + Funcs(map[string]interface{}{ + "pythonBool": func(isTrue bool) string { + if isTrue { + return "True" + } + return "False" + }, + }). + Parse(string(tplBytes)) + if err != nil { return nil, errors.Wrap(err, "Could not load template") } blessConfig := blessConfig{ - EncryptedPassword: d.Get(schemaEncryptedPassword).(string), - EncryptedPrivateKey: d.Get(schemaEncryptedPrivateKey).(string), - Name: d.Get(schemaServiceName).(string), - KMSAuthKeyID: d.Get(schemaKMSAuthKeyID).(string), + Name: d.Get(schemaServiceName).(string), + LoggingLevel: d.Get(schemaLoggingLevel).(string), + UsernameValidation: d.Get(schemaUsernameValidation).(string), + EncryptedPassword: d.Get(schemaEncryptedPassword).(string), + EncryptedPrivateKey: d.Get(schemaEncryptedPrivateKey).(string), + KMSAuthKeyID: d.Get(schemaKMSAuthKeyID).(string), + KMSAuthRemoteUsernamesAllowed: d.Get(schemaKMSAuthRemoteUsernamesAllowed).(string), + KMSAuthValidateRemoteUsernameAgainstIAMGroups: d.Get(schemaKMSAuthValidateRemoteUsernameAgainstIAMGroups).(bool), + KMSAuthIAMGroupNameFormat: d.Get(schemaKMSAuthIAMGroupNameFormat).(string), } + buff := bytes.NewBuffer(nil) err = t.Execute(buff, blessConfig) return buff, errors.Wrap(err, "Could not templetize config") @@ -161,7 +228,7 @@ func (l *resourceLambda) archive(d *schema.ResourceData, meta interface{}) error // Add all the python lambda files to the zip zipBox := packr.NewBox("../../bless_lambda/bless_ca") // HACK: zipBox.Walk does not guarantee a stable iteration order - files:= []string{} + files := []string{} err = zipBox.Walk(func(path string, f packr.File) error { fileInfo, err := f.FileInfo() if err != nil { @@ -191,6 +258,7 @@ func (l *resourceLambda) archive(d *schema.ResourceData, meta interface{}) error if err != nil { return err } + // Write the config return l.writeFileToZip(blessConfig, writer, "bless_deploy.cfg") } diff --git a/pkg/provider/data_lambda_test.go b/pkg/provider/data_lambda_test.go index 94e46357..c05b1278 100644 --- a/pkg/provider/data_lambda_test.go +++ b/pkg/provider/data_lambda_test.go @@ -47,8 +47,8 @@ func TestLambdaCreate(t *testing.T) { } `, Check: func(s *terraform.State) error { - output1:= s.RootModule().Outputs["output"].Value - output2:= s.RootModule().Outputs["output_2"].Value + output1 := s.RootModule().Outputs["output"].Value + output2 := s.RootModule().Outputs["output_2"].Value a.NotEmpty(output1) a.NotEmpty(output2) // Check hashes are equal @@ -57,6 +57,48 @@ func TestLambdaCreate(t *testing.T) { }, Destroy: true, }, + r.TestStep{ + Config: ` + provider "bless" { + region = "us-east-1" + } + + data "bless_lambda" "zip" { + encrypted_ca = "aaaa" + encrypted_password = "bbbb" + service_name = "test" + kmsauth_key_id = "keyID" + output_path = "/tmp/test3.zip" + } + + data "bless_lambda" "zip2" { + encrypted_ca = "aaaa" + encrypted_password = "bbbb" + service_name = "test" + kmsauth_key_id = "keyID" + output_path = "/tmp/test4.zip" + kmsauth_validate_remote_user = "false" # setting different field here + } + + + output "output" { + value = "${data.bless_lambda.zip.output_base64sha256}" + } + output "output_2" { + value = "${data.bless_lambda.zip2.output_base64sha256}" + } + `, + Check: func(s *terraform.State) error { + output1 := s.RootModule().Outputs["output"].Value + output2 := s.RootModule().Outputs["output_2"].Value + a.NotEmpty(output1) + a.NotEmpty(output2) + // Check hashes are equal + a.NotEqual(output1, output2) + return nil + }, + Destroy: true, + }, }, }) }