diff --git a/client/current_account.go b/client/current_account.go index 9572b76f..ffd2dd16 100644 --- a/client/current_account.go +++ b/client/current_account.go @@ -3,6 +3,7 @@ package client import ( "encoding/json" "fmt" + "github.com/stretchr/objx" ) @@ -11,13 +12,15 @@ type CurrentAccountUser struct { ID string `json:"id,omitempty"` UserName string `json:"name,omitempty"` Email string `json:"email,omitempty"` + Status string `json:"status,omitempty"` } // CurrentAccount spec type CurrentAccount struct { - ID string - Name string - Users []CurrentAccountUser + ID string + Name string + Users []CurrentAccountUser + Admins []CurrentAccountUser } // GetCurrentAccount - @@ -42,8 +45,9 @@ func (client *Client) GetCurrentAccount() (*CurrentAccount, error) { return nil, fmt.Errorf("GetCurrentAccount - cannot get activeAccountName") } currentAccount := &CurrentAccount{ - Name: activeAccountName, - Users: make([]CurrentAccountUser, 0), + Name: activeAccountName, + Users: make([]CurrentAccountUser, 0), + Admins: make([]CurrentAccountUser, 0), } allAccountsI := currentAccountX.Get("account").InterSlice() @@ -51,6 +55,19 @@ func (client *Client) GetCurrentAccount() (*CurrentAccount, error) { accX := objx.New(accI) if accX.Get("name").String() == activeAccountName { currentAccount.ID = accX.Get("id").String() + admins := accX.Get("admins").InterSlice() + for _, adminI := range admins { + admin, err := client.GetUserByID(adminI.(string)) + if err != nil { + return nil, err + } + currentAccount.Admins = append(currentAccount.Admins, CurrentAccountUser{ + ID: admin.ID, + UserName: admin.UserName, + Email: admin.Email, + Status: admin.Status, + }) + } break } } @@ -69,17 +86,19 @@ func (client *Client) GetCurrentAccount() (*CurrentAccount, error) { accountUsersI := make([]interface{}, 0) if e := json.Unmarshal(accountUsersResp, &accountUsersI); e != nil { - return nil, fmt.Errorf("Cannot unmarshal accountUsers responce for accountId=%s: %v", currentAccount.ID, e) + return nil, fmt.Errorf("cannot unmarshal accountUsers responce for accountId=%s: %v", currentAccount.ID, e) } for _, userI := range accountUsersI { userX := objx.New(userI) userName := userX.Get("userName").String() email := userX.Get("email").String() + status := userX.Get("status").String() userID := userX.Get("_id").String() currentAccount.Users = append(currentAccount.Users, CurrentAccountUser{ ID: userID, UserName: userName, Email: email, + Status: status, }) } diff --git a/client/user.go b/client/user.go index 47b9d4d4..68c52876 100644 --- a/client/user.go +++ b/client/user.go @@ -63,16 +63,22 @@ type UserAccounts struct { Account []Account `json:"account"` } -func (client *Client) AddNewUserToAccount(accountId, userName, userEmail string) (*User, error) { +// The API accepts two different schemas when updating the user details +func generateUserDetailsBody(userName, userEmail string) string { + userDetails := fmt.Sprintf(`{"userDetails": "%s"}`, userEmail) + if userName != "" { + userDetails = fmt.Sprintf(`{"userName": "%s", "email": "%s"}`, userName, userEmail) + } + return userDetails +} - userDetails := fmt.Sprintf(`{"userName": "%s", "email": "%s"}`, userName, userEmail) +func (client *Client) AddNewUserToAccount(accountId, userName, userEmail string) (*User, error) { fullPath := fmt.Sprintf("/accounts/%s/adduser", accountId) - opts := RequestOptions{ Path: fullPath, Method: "POST", - Body: []byte(userDetails), + Body: []byte(generateUserDetailsBody(userName, userEmail)), } resp, err := client.RequestAPI(&opts) @@ -338,3 +344,27 @@ func (client *Client) UpdateUserAccounts(userId string, accounts []Account) erro return nil } + +func (client *Client) UpdateUserDetails(accountId, userId, userName, userEmail string) (*User, error) { + + fullPath := fmt.Sprintf("/accounts/%s/%s/updateuser", accountId, userId) + opts := RequestOptions{ + Path: fullPath, + Method: "POST", + Body: []byte(generateUserDetailsBody(userName, userEmail)), + } + + resp, err := client.RequestAPI(&opts) + if err != nil { + return nil, err + } + + var respUser User + + err = DecodeResponseInto(resp, &respUser) + if err != nil { + return nil, err + } + + return &respUser, nil +} diff --git a/codefresh/provider.go b/codefresh/provider.go index ffe6c0d1..5a7003a1 100644 --- a/codefresh/provider.go +++ b/codefresh/provider.go @@ -53,20 +53,21 @@ func Provider() *schema.Provider { "codefresh_pipelines": dataSourcePipelines(), }, ResourcesMap: map[string]*schema.Resource{ - "codefresh_account": resourceAccount(), - "codefresh_account_admins": resourceAccountAdmins(), - "codefresh_api_key": resourceApiKey(), - "codefresh_context": resourceContext(), - "codefresh_registry": resourceRegistry(), - "codefresh_idp_accounts": resourceIDPAccounts(), - "codefresh_permission": resourcePermission(), - "codefresh_pipeline": resourcePipeline(), - "codefresh_pipeline_cron_trigger": resourcePipelineCronTrigger(), - "codefresh_project": resourceProject(), - "codefresh_step_types": resourceStepTypes(), - "codefresh_user": resourceUser(), - "codefresh_team": resourceTeam(), - "codefresh_abac_rules": resourceGitopsAbacRule(), + "codefresh_account": resourceAccount(), + "codefresh_account_user_association": resourceAccountUserAssociation(), + "codefresh_account_admins": resourceAccountAdmins(), + "codefresh_api_key": resourceApiKey(), + "codefresh_context": resourceContext(), + "codefresh_registry": resourceRegistry(), + "codefresh_idp_accounts": resourceIDPAccounts(), + "codefresh_permission": resourcePermission(), + "codefresh_pipeline": resourcePipeline(), + "codefresh_pipeline_cron_trigger": resourcePipelineCronTrigger(), + "codefresh_project": resourceProject(), + "codefresh_step_types": resourceStepTypes(), + "codefresh_user": resourceUser(), + "codefresh_team": resourceTeam(), + "codefresh_abac_rules": resourceGitopsAbacRule(), }, ConfigureFunc: configureProvider, } diff --git a/codefresh/provider_test.go b/codefresh/provider_test.go index ac007c8e..7fa6bce1 100644 --- a/codefresh/provider_test.go +++ b/codefresh/provider_test.go @@ -24,7 +24,7 @@ func TestProvider(t *testing.T) { } func testAccPreCheck(t *testing.T) { - if v := os.Getenv("CODEFRESH_API_KEY"); v == "" { - t.Fatal("CODEFRESH_API_KEY must be set for acceptance tests") + if v := os.Getenv(ENV_CODEFRESH_API_KEY); v == "" { + t.Fatalf("%s must be set for acceptance tests", ENV_CODEFRESH_API_KEY) } } diff --git a/codefresh/resource_account_user_association.go b/codefresh/resource_account_user_association.go new file mode 100644 index 00000000..7b3e9f02 --- /dev/null +++ b/codefresh/resource_account_user_association.go @@ -0,0 +1,169 @@ +package codefresh + +import ( + "context" + "fmt" + + cfClient "github.com/codefresh-io/terraform-provider-codefresh/client" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceAccountUserAssociation() *schema.Resource { + return &schema.Resource{ + Description: ` + Associates a user with the account which the provider is authenticated against. If the user is not present in the system, an invitation will be sent to the specified email address. + `, + Create: resourceAccountUserAssociationCreate, + Read: resourceAccountUserAssociationRead, + Update: resourceAccountUserAssociationUpdate, + Delete: resourceAccountUserAssociationDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "email": { + Description: ` + The email of the user to associate with the specified account. + If the user is not present in the system, an invitation will be sent to this email. + This field can only be changed when 'status' is 'pending'. + `, + Type: schema.TypeString, + Required: true, + }, + "admin": { + Description: "Whether to make this user an account admin.", + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "username": { + Computed: true, + Type: schema.TypeString, + Description: "The username of the associated user.", + }, + "status": { + Computed: true, + Type: schema.TypeString, + Description: "The status of the association.", + }, + }, + CustomizeDiff: customdiff.All( + // The email field is immutable, except for users with status "pending". + customdiff.ForceNewIf("email", func(_ context.Context, d *schema.ResourceDiff, _ any) bool { + return d.Get("status").(string) != "pending" && d.HasChange("email") + }), + ), + } +} + +func resourceAccountUserAssociationCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*cfClient.Client) + currentAccount, err := client.GetCurrentAccount() + if err != nil { + return err + } + + user, err := client.AddNewUserToAccount(currentAccount.ID, "", d.Get("email").(string)) + if err != nil { + return err + } + + d.SetId(user.ID) + + if d.Get("admin").(bool) { + err = client.SetUserAsAccountAdmin(currentAccount.ID, d.Id()) + if err != nil { + return err + } + } + + d.Set("status", user.Status) + + return nil +} + +func resourceAccountUserAssociationRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*cfClient.Client) + currentAccount, err := client.GetCurrentAccount() + if err != nil { + return err + } + + userID := d.Id() + if userID == "" { + d.SetId("") + return nil + } + + for _, user := range currentAccount.Users { + if user.ID == userID { + d.Set("email", user.Email) + d.Set("username", user.UserName) + d.Set("status", user.Status) + d.Set("admin", false) // avoid missing attributes after import + for _, admin := range currentAccount.Admins { + if admin.ID == userID { + d.Set("admin", true) + } + } + } + } + + if d.Id() == "" { + return fmt.Errorf("a user with ID %s was not found", userID) + } + + return nil +} + +func resourceAccountUserAssociationUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*cfClient.Client) + + currentAccount, err := client.GetCurrentAccount() + if err != nil { + return err + } + + if d.HasChange("email") { + user, err := client.UpdateUserDetails(currentAccount.ID, d.Id(), d.Get("username").(string), d.Get("email").(string)) + if err != nil { + return err + } + if user.Email != d.Get("email").(string) { + return fmt.Errorf("failed to update user email, despite successful API response") + } + } + + if d.HasChange("admin") { + if d.Get("admin").(bool) { + err = client.SetUserAsAccountAdmin(currentAccount.ID, d.Id()) + if err != nil { + return err + } + } else { + err = client.DeleteUserAsAccountAdmin(currentAccount.ID, d.Id()) + if err != nil { + return err + } + } + } + + return nil +} + +func resourceAccountUserAssociationDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*cfClient.Client) + + currentAccount, err := client.GetCurrentAccount() + if err != nil { + return err + } + + err = client.DeleteUserFromAccount(currentAccount.ID, d.Id()) + if err != nil { + return err + } + + return nil +} diff --git a/codefresh/resource_account_user_association_test.go b/codefresh/resource_account_user_association_test.go new file mode 100644 index 00000000..426317d3 --- /dev/null +++ b/codefresh/resource_account_user_association_test.go @@ -0,0 +1,193 @@ +package codefresh + +import ( + "fmt" + "testing" + + cfClient "github.com/codefresh-io/terraform-provider-codefresh/client" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func testAccCodefreshAccountUserAssociationGenerateUserEmail() string { + randomEmailFormat := "terraform-test-user+%s@codefresh.io" // use + addressing + return fmt.Sprintf(randomEmailFormat, acctest.RandString(10)) +} + +func testAccCodefreshActivateUser(s *terraform.State, email string) error { + c := testAccProvider.Meta().(*cfClient.Client) + currentAccount, err := c.GetCurrentAccount() + if err != nil { + return fmt.Errorf("failed to get current account: %s", err) + } + for _, user := range currentAccount.Users { + if user.Email == email { + _, err = c.ActivateUser(user.ID) + if err != nil { + return fmt.Errorf("failed to activate user: %s", err) + } + } + } + return nil +} + +func TestAccCodefreshAccountUserAssociation_Activation(t *testing.T) { + resourceName := "codefresh_account_user_association.test_user" + + testUserEmail := testAccCodefreshAccountUserAssociationGenerateUserEmail() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCodefreshAccountUserAssociationConfig(testUserEmail, true), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "email", testUserEmail), + resource.TestCheckResourceAttr(resourceName, "admin", "true"), + resource.TestCheckResourceAttr(resourceName, "status", "pending"), + ), + }, + { + RefreshState: true, + Check: func(s *terraform.State) error { + return testAccCodefreshActivateUser(s, testUserEmail) + }, + }, + { + RefreshState: true, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "status", "new"), + ), + }, + { + // Test resource import + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccCodefreshAccountUserAssociation_StatusPending_Email_ForceNew(t *testing.T) { + resourceName := "codefresh_account_user_association.test_user" + + testUserEmailBefore := testAccCodefreshAccountUserAssociationGenerateUserEmail() + testUserEmailAfter := testAccCodefreshAccountUserAssociationGenerateUserEmail() + var resourceId string + var err error + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCodefreshAccountUserAssociationConfig(testUserEmailBefore, true), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "email", testUserEmailBefore), + resource.TestCheckResourceAttr(resourceName, "admin", "true"), + resource.TestCheckResourceAttr(resourceName, "status", "pending"), + ), + }, + { + RefreshState: true, + Check: func(s *terraform.State) error { + resourceId, err = testAccGetResourceId(s, resourceName) + return err + }, + }, + { + Config: testAccCodefreshAccountUserAssociationConfig(testUserEmailAfter, true), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "email", testUserEmailAfter), + resource.TestCheckResourceAttr(resourceName, "admin", "true"), + resource.TestCheckResourceAttr(resourceName, "status", "pending"), + ), + }, + { + // Test that an email change on a pending user does NOT force a new resource + RefreshState: true, + Check: func(s *terraform.State) error { + newResourceId, err := testAccGetResourceId(s, resourceName) + if err != nil { + return err + } + if resourceId != newResourceId { + return fmt.Errorf("did not expect email change on pending user to force a new resource") + } + return nil + }, + }, + }, + }) +} + +func TestAccCodefreshAccountUserAssociation_StatusNew_Email_ForceNew(t *testing.T) { + resourceName := "codefresh_account_user_association.test_user" + + testUserEmailBefore := testAccCodefreshAccountUserAssociationGenerateUserEmail() + testUserEmailAfter := testAccCodefreshAccountUserAssociationGenerateUserEmail() + var resourceId string + var err error + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCodefreshAccountUserAssociationConfig(testUserEmailBefore, true), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "email", testUserEmailBefore), + resource.TestCheckResourceAttr(resourceName, "admin", "true"), + resource.TestCheckResourceAttr(resourceName, "status", "pending"), + ), + }, + { + RefreshState: true, + Check: func(s *terraform.State) error { + resourceId, err = testAccGetResourceId(s, resourceName) + return err + }, + }, + { + RefreshState: true, + Check: func(s *terraform.State) error { + return testAccCodefreshActivateUser(s, testUserEmailBefore) + }, + }, + { + // Test that an email change on an activated user DOES force a new resource + Config: testAccCodefreshAccountUserAssociationConfig(testUserEmailAfter, true), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "email", testUserEmailAfter), + resource.TestCheckResourceAttr(resourceName, "admin", "true"), + resource.TestCheckResourceAttr(resourceName, "status", "pending"), // status should be pending because a new resource was forced + ), + }, + { + RefreshState: true, + Check: func(s *terraform.State) error { + newResourceId, err := testAccGetResourceId(s, resourceName) + if err != nil { + return err + } + if resourceId == newResourceId { + return fmt.Errorf("expected email change on activated user to force a new resource") + } + return nil + }, + }, + }, + }) +} + +func testAccCodefreshAccountUserAssociationConfig(email string, admin bool) string { + return fmt.Sprintf(` +resource "codefresh_account_user_association" "test_user" { + email = "%s" + admin = %t +} +`, email, admin) +} diff --git a/codefresh/resource_user.go b/codefresh/resource_user.go index d0463f12..a6fa3bc7 100644 --- a/codefresh/resource_user.go +++ b/codefresh/resource_user.go @@ -129,7 +129,7 @@ func resourceUsersCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*cfClient.Client) - user := mapResourceToUser(d) + user := mapResourceToNewUser(d) resp, err := client.AddPendingUser(user) if err != nil { @@ -265,7 +265,7 @@ func flattenUserLogins(logins *[]cfClient.Login) []map[string]interface{} { return res } -func mapResourceToUser(d *schema.ResourceData) *cfClient.NewUser { +func mapResourceToNewUser(d *schema.ResourceData) *cfClient.NewUser { roles := d.Get("roles").(*schema.Set).List() accounts := d.Get("accounts").(*schema.Set).List() diff --git a/codefresh/utils.go b/codefresh/utils.go index 99829be1..a60ebf15 100644 --- a/codefresh/utils.go +++ b/codefresh/utils.go @@ -3,18 +3,20 @@ package codefresh import ( "bytes" "fmt" - "github.com/sclevine/yj/convert" + "io/ioutil" "log" "regexp" "strings" + "github.com/sclevine/yj/convert" + cfClient "github.com/codefresh-io/terraform-provider-codefresh/client" "github.com/dlclark/regexp2" "github.com/ghodss/yaml" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/mikefarah/yq/v4/pkg/yqlib" logging "gopkg.in/op/go-logging.v1" - "io/ioutil" ) func convertStringArr(ifaceArr []interface{}) []string { @@ -161,3 +163,11 @@ func yamlToJson(yamlString string) (string, error) { return jsonBuffer.String(), nil } + +func testAccGetResourceId(s *terraform.State, resourceName string) (string, error) { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return "", fmt.Errorf("resource %s not found", resourceName) + } + return rs.Primary.ID, nil +} \ No newline at end of file diff --git a/docs/resources/account_user_association.md b/docs/resources/account_user_association.md new file mode 100644 index 00000000..390ecd7b --- /dev/null +++ b/docs/resources/account_user_association.md @@ -0,0 +1,66 @@ +--- +page_title: "codefresh_account_user_association Resource - terraform-provider-codefresh" +subcategory: "" +description: |- + Associates a user with the account which the provider is authenticated against. If the user is not present in the system, an invitation will be sent to the specified email address. +--- + +# codefresh_account_user_association (Resource) + +Associates a user with the account which the provider is authenticated against. If the user is not present in the system, an invitation will be sent to the specified email address. + +See the [documentation](https://codefresh.io/docs/docs/administration/account-user-management/add-users/#users-in-codefresh). + +## Example usage + +```hcl +locals { + users = { + ed = { + email = "ed@rethink.io", + admin = true, + } + edd = { + email = "edd@rethink.io", + admin = true, + } + eddy = { + email = "eddy@rethink.io", + admin = false, + } + } +} + +resource "codefresh_account_user_association" "users" { + for_each = local.users, + email = each.value.email, + admin = each.value.admin, +} +``` + + +## Schema + +### Required + +- `email` (String) The email of the user to associate with the specified account. + If the user is not present in the system, an invitation will be sent to this email. + This field can only be changed when 'status' is 'pending'. + +### Optional + +- `admin` (Boolean) Whether to make this user an account admin. + +### Read-Only + +- `id` (String) The ID of this resource. +- `status` (String) The status of the association. +- `username` (String) The username of the associated user. + +## Import + +An existing account user association can be imported via the user ID: + +```sh +terraform import codefresh_account_user_association.test_user xxxxxxxxxxxxxxxxxxx +``` \ No newline at end of file diff --git a/examples/account_user_associations/main.tf b/examples/account_user_associations/main.tf new file mode 100644 index 00000000..c7c06102 --- /dev/null +++ b/examples/account_user_associations/main.tf @@ -0,0 +1,8 @@ +resource "codefresh_account_user_association" "user" { + email = "terraform-test-user+user@codefresh.io" +} + +resource "codefresh_account_user_association" "admin" { + email = "terraform-test-user+admin@codefresh.io" + admin = true +} \ No newline at end of file diff --git a/examples/account_user_associations/versions.tf b/examples/account_user_associations/versions.tf new file mode 100644 index 00000000..588936b9 --- /dev/null +++ b/examples/account_user_associations/versions.tf @@ -0,0 +1,7 @@ +terraform { + required_providers { + codefresh = { + source = "codefresh-io/codefresh" + } + } +} \ No newline at end of file diff --git a/go.mod b/go.mod index d0d76f25..c6d7872f 100644 --- a/go.mod +++ b/go.mod @@ -26,6 +26,11 @@ require ( require ( 4d63.com/gocheckcompilerdirectives v1.2.1 // indirect 4d63.com/gochecknoglobals v0.2.1 // indirect + cloud.google.com/go v0.110.0 // indirect + cloud.google.com/go/compute v1.19.0 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/iam v0.13.0 // indirect + cloud.google.com/go/storage v1.28.1 // indirect github.com/Abirdcfly/dupword v0.0.11 // indirect github.com/Antonboom/errname v0.1.9 // indirect github.com/Antonboom/nilnil v0.1.4 // indirect @@ -41,12 +46,15 @@ require ( github.com/alecthomas/participle/v2 v2.0.0 // indirect github.com/alexkohler/prealloc v1.0.0 // indirect github.com/alingse/asasalint v0.0.11 // indirect + github.com/apparentlymart/go-cidr v1.1.0 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/armon/go-radix v1.0.0 // indirect github.com/ashanbrown/forbidigo v1.5.1 // indirect github.com/ashanbrown/makezero v1.1.1 // indirect + github.com/aws/aws-sdk-go v1.37.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bflad/gopaniccheck v0.1.0 // indirect + github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.1.0 // indirect github.com/bkielbasa/cyclop v1.2.0 // indirect github.com/blizzy78/varnamelen v0.8.0 // indirect @@ -84,6 +92,7 @@ require ( github.com/goccy/go-json v0.10.2 // indirect github.com/goccy/go-yaml v1.11.0 // indirect github.com/gofrs/flock v0.8.1 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect @@ -96,6 +105,8 @@ require ( github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect + github.com/googleapis/gax-go/v2 v2.7.1 // indirect github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect github.com/gostaticanalysis/comment v1.4.2 // indirect @@ -104,9 +115,11 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-getter v1.5.3 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-plugin v1.4.9 // indirect + github.com/hashicorp/go-safetemp v1.0.0 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/hc-install v0.5.0 // indirect @@ -127,11 +140,13 @@ require ( github.com/jingyugao/rowserrcheck v1.1.1 // indirect github.com/jinzhu/copier v0.3.5 // indirect github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/julz/importas v0.1.0 // indirect github.com/junk1tm/musttag v0.5.0 // indirect github.com/kisielk/errcheck v1.6.3 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.4 // indirect + github.com/klauspost/compress v1.11.2 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.6 // indirect github.com/kyoh86/exportloopref v0.1.11 // indirect @@ -209,6 +224,7 @@ require ( github.com/timonwong/loggercheck v0.9.4 // indirect github.com/tomarrell/wrapcheck/v2 v2.8.1 // indirect github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect + github.com/ulikunitz/xz v0.5.8 // indirect github.com/ultraware/funlen v0.0.3 // indirect github.com/ultraware/whitespace v0.0.5 // indirect github.com/uudashr/gocognit v1.0.6 // indirect @@ -220,7 +236,9 @@ require ( github.com/yuin/goldmark v1.5.4 // indirect github.com/yuin/goldmark-meta v1.1.0 // indirect github.com/zclconf/go-cty v1.13.1 // indirect + github.com/zclconf/go-cty-yaml v1.0.2 // indirect gitlab.com/bosi/decorder v0.2.3 // indirect + go.opencensus.io v0.24.0 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect @@ -229,11 +247,13 @@ require ( golang.org/x/exp/typeparams v0.0.0-20230321023759-10a507213a29 // indirect golang.org/x/mod v0.10.0 // indirect golang.org/x/net v0.9.0 // indirect + golang.org/x/oauth2 v0.6.0 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.7.0 // indirect golang.org/x/text v0.9.0 // indirect golang.org/x/tools v0.8.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/api v0.114.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect google.golang.org/grpc v1.54.0 // indirect diff --git a/go.sum b/go.sum index 81d41568..68d6e844 100644 --- a/go.sum +++ b/go.sum @@ -21,14 +21,22 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= +cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v1.19.0 h1:+9zda3WGgW1ZSTlVppLCYFIr48Pa35q1uG2N1itbCEQ= +cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/iam v0.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k= +cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -39,6 +47,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.28.1 h1:F5QDG5ChchaAVQhINh24U99OWHURqrW8OmQcGKXcbgI= +cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Abirdcfly/dupword v0.0.11 h1:z6v8rMETchZXUIuHxYNmlUAuKuB21PeaSymTed16wgU= github.com/Abirdcfly/dupword v0.0.11/go.mod h1:wH8mVGuf3CP5fsBTkfWwwwKTjDnVVCxtU8d8rgeVYXA= @@ -99,6 +109,7 @@ github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQ github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= github.com/andybalholm/crlf v0.0.0-20171020200849-670099aa064f/go.mod h1:k8feO4+kXDxro6ErPXBRTJ/ro2mf0SsFG8s7doP9kJE= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU= github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= @@ -115,6 +126,7 @@ github.com/ashanbrown/forbidigo v1.5.1/go.mod h1:Y8j9jy9ZYAEHXdu723cUlraTqbzjKF1 github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= +github.com/aws/aws-sdk-go v1.37.0 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk= github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -128,6 +140,7 @@ github.com/bflad/tfproviderdocs v0.9.1 h1:C9Rkh61PgaQnRLbgfuBKRGCS8C8d8yEla3gpTo github.com/bflad/tfproviderdocs v0.9.1/go.mod h1:gC+fjQ+tT1x1bqq+2yZ9G/y9VjRI24c6HDi+uEdgBG4= github.com/bflad/tfproviderlint v0.29.0 h1:zxKYAAM6IZ4ace1a3LX+uzMRIMP8L+iOtEc+FP2Yoow= github.com/bflad/tfproviderlint v0.29.0/go.mod h1:ErKVd+GRA2tXKr8T7zC0EDSrtALJL25wj0ZJ/v/klqQ= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= @@ -272,6 +285,8 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -329,6 +344,7 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -354,8 +370,12 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6cvPr8A= +github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 h1:9alfqbrhuD+9fLZ4iaAVwhlp5PEhmnBt7yvK2Oy5C1U= github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= @@ -381,6 +401,7 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= +github.com/hashicorp/go-getter v1.5.3 h1:NF5+zOlQegim+w/EUhSLh6QhXHmZMEeHLQzllkQ3ROU= github.com/hashicorp/go-getter v1.5.3/go.mod h1:BrrV/1clo8cCYu6mxvboYg+KutTiFnXjMEgDD8+i7ZI= github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= @@ -393,6 +414,7 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/go-plugin v1.3.0/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYtXdgmf1AVNs0= github.com/hashicorp/go-plugin v1.4.9 h1:ESiK220/qE0aGxWdzKIvRH69iLiuN/PjoLTm69RoWtU= github.com/hashicorp/go-plugin v1.4.9/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= +github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -474,6 +496,7 @@ github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -498,6 +521,7 @@ github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt0GMb8= github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg= +github.com/klauspost/compress v1.11.2 h1:MiK62aErc3gIiVEtyzKfeOHgW7atJb5g/KNX5m3c2nQ= github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -792,6 +816,7 @@ github.com/tomarrell/wrapcheck/v2 v2.8.1 h1:HxSqDSN0sAt0yJYsrcYVoEeyM4aI9yAm3KQp github.com/tomarrell/wrapcheck/v2 v2.8.1/go.mod h1:/n2Q3NZ4XFT50ho6Hbxg+RV1uyo2Uow/Vdm9NQcl5SE= github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw= github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= +github.com/ulikunitz/xz v0.5.8 h1:ERv8V6GKqVi23rgu5cj9pVfVzJbOqAY2Ntl88O6c2nQ= github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= @@ -835,6 +860,7 @@ github.com/zclconf/go-cty v1.8.2/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUA github.com/zclconf/go-cty v1.13.1 h1:0a6bRwuiSHtAmqCqNOE+c2oHgepv0ctoxU4FUe43kwc= github.com/zclconf/go-cty v1.13.1/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= +github.com/zclconf/go-cty-yaml v1.0.2 h1:dNyg4QLTrv2IfJpm7Wtxi55ed5gLGOlPrZ6kMd51hY0= github.com/zclconf/go-cty-yaml v1.0.2/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0= gitlab.com/bosi/decorder v0.2.3 h1:gX4/RgK16ijY8V+BRQHAySfQAb354T7/xQpDB2n10P0= gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE= @@ -844,6 +870,8 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= @@ -979,6 +1007,8 @@ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1193,6 +1223,8 @@ google.golang.org/api v0.34.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.114.0 h1:1xQPji6cO2E2vLiI+C/XiFAnsn1WV3mjaEwGLhi3grE= +google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= diff --git a/templates/resources/account_user_association.md.tmpl b/templates/resources/account_user_association.md.tmpl new file mode 100644 index 00000000..57c0d71b --- /dev/null +++ b/templates/resources/account_user_association.md.tmpl @@ -0,0 +1,49 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +subcategory: "" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +See the [documentation](https://codefresh.io/docs/docs/administration/account-user-management/add-users/#users-in-codefresh). + +## Example usage + +```hcl +locals { + users = { + ed = { + email = "ed@rethink.io", + admin = true, + } + edd = { + email = "edd@rethink.io", + admin = true, + } + eddy = { + email = "eddy@rethink.io", + admin = false, + } + } +} + +resource "codefresh_account_user_association" "users" { + for_each = local.users, + email = each.value.email, + admin = each.value.admin, +} +``` + +{{ .SchemaMarkdown | trimspace }} + +## Import + +An existing account user association can be imported via the user ID: + +```sh +terraform import codefresh_account_user_association.test_user xxxxxxxxxxxxxxxxxxx +``` \ No newline at end of file diff --git a/tf_modules/accounts_users/main.tf b/tf_modules/accounts_users/main.tf index e350db54..4578dfde 100644 --- a/tf_modules/accounts_users/main.tf +++ b/tf_modules/accounts_users/main.tf @@ -66,4 +66,4 @@ resource "codefresh_account_admins" "acc_admins" { for k, u in var.users: codefresh_user.users[k].id if contains(u.admin_of_accounts, each.key) ] -} +} \ No newline at end of file