diff --git a/builtin/providers/rancher/resource_rancher_environment.go b/builtin/providers/rancher/resource_rancher_environment.go index 99c79c61b4..39025855e7 100644 --- a/builtin/providers/rancher/resource_rancher_environment.go +++ b/builtin/providers/rancher/resource_rancher_environment.go @@ -41,6 +41,27 @@ func resourceRancherEnvironment() *schema.Resource { Type: schema.TypeString, Optional: true, }, + "member": &schema.Schema{ + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "external_id_type": { + Type: schema.TypeString, + Required: true, + }, + "external_id": { + Type: schema.TypeString, + Required: true, + }, + "role": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, }, } } @@ -85,6 +106,21 @@ func resourceRancherEnvironmentCreate(d *schema.ResourceData, meta interface{}) d.SetId(newEnv.Id) log.Printf("[INFO] Environment ID: %s", d.Id()) + // Add members + if v, ok := d.GetOk("member"); ok { + envClient, err := meta.(*Config).EnvironmentClient(d.Id()) + if err != nil { + return err + } + members := v.([]interface{}) + _, err = envClient.Project.ActionSetmembers(&newEnv, &rancherClient.SetProjectMembersInput{ + Members: members, + }) + if err != nil { + return err + } + } + return resourceRancherEnvironmentRead(d, meta) } @@ -118,6 +154,14 @@ func resourceRancherEnvironmentRead(d *schema.ResourceData, meta interface{}) er d.Set("name", env.Name) d.Set("orchestration", getActiveOrchestration(env)) + envClient, err := meta.(*Config).EnvironmentClient(d.Id()) + if err != nil { + return err + } + + members, _ := envClient.ProjectMember.List(NewListOpts()) + + d.Set("member", normalizeMembers(members.Data)) return nil } @@ -148,6 +192,19 @@ func resourceRancherEnvironmentUpdate(d *schema.ResourceData, meta interface{}) return err } + // Update members + envClient, err := meta.(*Config).EnvironmentClient(d.Id()) + if err != nil { + return err + } + members := d.Get("member").(*schema.Set).List() + _, err = envClient.Project.ActionSetmembers(&newEnv, &rancherClient.SetProjectMembersInput{ + Members: makeProjectMembers(members), + }) + if err != nil { + return err + } + return resourceRancherEnvironmentRead(d, meta) } @@ -203,6 +260,31 @@ func setOrchestrationFields(orchestration string, data map[string]interface{}) { data[orch] = true } +func normalizeMembers(in []rancherClient.ProjectMember) (out []interface{}) { + for _, m := range in { + mm := map[string]string{ + "external_id_type": m.ExternalIdType, + "external_id": m.ExternalId, + "role": m.Role, + } + out = append(out, mm) + } + return +} + +func makeProjectMembers(in []interface{}) (out []interface{}) { + for _, m := range in { + mMap := m.(map[string]interface{}) + mm := rancherClient.ProjectMember{ + ExternalIdType: mMap["external_id_type"].(string), + ExternalId: mMap["external_id"].(string), + Role: mMap["role"].(string), + } + out = append(out, mm) + } + return +} + // EnvironmentStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch // a Rancher Environment. func EnvironmentStateRefreshFunc(client *rancherClient.RancherClient, environmentID string) resource.StateRefreshFunc { diff --git a/builtin/providers/rancher/resource_rancher_environment_test.go b/builtin/providers/rancher/resource_rancher_environment_test.go index ec8a81d7c7..6474efaf61 100644 --- a/builtin/providers/rancher/resource_rancher_environment_test.go +++ b/builtin/providers/rancher/resource_rancher_environment_test.go @@ -60,6 +60,38 @@ func TestAccRancherEnvironment_disappears(t *testing.T) { }) } +func TestAccRancherEnvironment_members(t *testing.T) { + var environment rancherClient.Project + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckRancherEnvironmentDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccRancherEnvironmentMembersConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckRancherEnvironmentExists("rancher_environment.foo", &environment), + resource.TestCheckResourceAttr("rancher_environment.foo", "name", "foo"), + resource.TestCheckResourceAttr("rancher_environment.foo", "description", "Terraform acc test group"), + resource.TestCheckResourceAttr("rancher_environment.foo", "orchestration", "cattle"), + resource.TestCheckResourceAttr("rancher_environment.foo", "member.#", "2"), + ), + }, + resource.TestStep{ + Config: testAccRancherEnvironmentMembersUpdateConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckRancherEnvironmentExists("rancher_environment.foo", &environment), + resource.TestCheckResourceAttr("rancher_environment.foo", "name", "foo2"), + resource.TestCheckResourceAttr("rancher_environment.foo", "description", "Terraform acc test group - updated"), + resource.TestCheckResourceAttr("rancher_environment.foo", "orchestration", "swarm"), + resource.TestCheckResourceAttr("rancher_environment.foo", "member.#", "1"), + ), + }, + }, + }) +} + func testAccRancherEnvironmentDisappears(env *rancherClient.Project) resource.TestCheckFunc { return func(s *terraform.State) error { client, err := testAccProvider.Meta().(*Config).GlobalClient() @@ -159,3 +191,37 @@ resource "rancher_environment" "foo" { orchestration = "swarm" } ` + +const testAccRancherEnvironmentMembersConfig = ` +resource "rancher_environment" "foo" { + name = "foo" + description = "Terraform acc test group" + orchestration = "cattle" + + member { + external_id = "1234" + external_id_type = "github_user" + role = "owner" + } + + member { + external_id = "8765" + external_id_type = "github_team" + role = "member" + } +} +` + +const testAccRancherEnvironmentMembersUpdateConfig = ` +resource "rancher_environment" "foo" { + name = "foo" + description = "Terraform acc test group" + orchestration = "cattle" + + member { + external_id = "1235" + external_id_type = "github_user" + role = "owner" + } +} +` diff --git a/website/source/docs/providers/rancher/r/environment.html.md b/website/source/docs/providers/rancher/r/environment.html.md index cb4c1b8f68..0e2548b78a 100644 --- a/website/source/docs/providers/rancher/r/environment.html.md +++ b/website/source/docs/providers/rancher/r/environment.html.md @@ -18,6 +18,18 @@ resource "rancher_environment" "default" { name = "staging" description = "The staging environment" orchestration = "cattle" + + member { + external_id = "650430" + external_id_type = "github_user" + role = "owner" + } + + member { + external_id = "1234" + external_id_type = "github_team" + role = "member" + } } ``` @@ -28,6 +40,16 @@ The following arguments are supported: * `name` - (Required) The name of the environment. * `description` - (Optional) An environment description. * `orchestration` - (Optional) Must be one of **cattle**, **swarm**, **mesos** or **kubernetes**. Defaults to **cattle**. +* `member` - (Optional) Members to add to the environment. + +### Member Parameters Reference + +A `member` takes three parameters: + +* `external_id` - (Required) The external ID of the member. +* `external_id_type` - (Required) The external ID type of the member. +* `role` - (Required) The role of the member in the environment. + ## Attributes Reference