diff --git a/builtin/bins/provider-rancher/main.go b/builtin/bins/provider-rancher/main.go new file mode 100644 index 000000000000..adad816361b3 --- /dev/null +++ b/builtin/bins/provider-rancher/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "github.com/hashicorp/terraform/builtin/providers/rancher" + "github.com/hashicorp/terraform/plugin" + "github.com/hashicorp/terraform/terraform" +) + +func main() { + plugin.Serve(&plugin.ServeOpts{ + ProviderFunc: func() terraform.ResourceProvider { + return rancher.Provider() + }, + }) +} diff --git a/builtin/providers/rancher/config.go b/builtin/providers/rancher/config.go index 86a02e6cc4a3..a17a91ab6854 100644 --- a/builtin/providers/rancher/config.go +++ b/builtin/providers/rancher/config.go @@ -3,12 +3,12 @@ package rancher import ( "log" - rancher "github.com/rancher/go-rancher/client" + rancherClient "github.com/rancher/go-rancher/client" "github.com/raphink/go-rancher/catalog" ) type Config struct { - *rancher.RancherClient + *rancherClient.RancherClient APIURL string AccessKey string SecretKey string @@ -16,11 +16,7 @@ type Config struct { // Create creates a generic Rancher client func (c *Config) CreateClient() error { - if c.APIURL == "" || c.AccessKey == "" || c.SecretKey == "" { - return nil - } - - client, err := rancher.NewRancherClient(&rancher.ClientOpts{ + client, err := rancherClient.NewRancherClient(&rancherClient.ClientOpts{ Url: c.APIURL, AccessKey: c.AccessKey, SecretKey: c.SecretKey, @@ -36,13 +32,10 @@ func (c *Config) CreateClient() error { return nil } -func (c *Config) EnvironmentClient(env string) (*rancher.RancherClient, error) { - if c.APIURL == "" || c.AccessKey == "" || c.SecretKey == "" { - return nil, nil - } +func (c *Config) EnvironmentClient(env string) (*rancherClient.RancherClient, error) { url := c.APIURL + "/projects/" + env + "/schemas" - client, err := rancher.NewRancherClient(&rancher.ClientOpts{ + client, err := rancherClient.NewRancherClient(&rancherClient.ClientOpts{ Url: url, AccessKey: c.AccessKey, SecretKey: c.SecretKey, @@ -56,7 +49,7 @@ func (c *Config) EnvironmentClient(env string) (*rancher.RancherClient, error) { return client, nil } -func (c *Config) RegistryClient(id string) (*rancher.RancherClient, error) { +func (c *Config) RegistryClient(id string) (*rancherClient.RancherClient, error) { reg, err := c.Registry.ById(id) if err != nil { return nil, err @@ -66,9 +59,6 @@ func (c *Config) RegistryClient(id string) (*rancher.RancherClient, error) { } func (c *Config) CatalogClient() (*catalog.RancherClient, error) { - if c.APIURL == "" || c.AccessKey == "" || c.SecretKey == "" { - return nil, nil - } url := c.APIURL + "-catalog/schemas" client, err := catalog.NewRancherClient(&catalog.ClientOpts{ diff --git a/builtin/providers/rancher/import_rancher_environment_test.go b/builtin/providers/rancher/import_rancher_environment_test.go index c845b082db47..0b2a52173946 100644 --- a/builtin/providers/rancher/import_rancher_environment_test.go +++ b/builtin/providers/rancher/import_rancher_environment_test.go @@ -19,10 +19,9 @@ func TestAccRancherEnvironment_importBasic(t *testing.T) { }, resource.TestStep{ - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{}, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, }, }, }) diff --git a/builtin/providers/rancher/import_rancher_registration_token_test.go b/builtin/providers/rancher/import_rancher_registration_token_test.go new file mode 100644 index 000000000000..24a0b9b8a8e9 --- /dev/null +++ b/builtin/providers/rancher/import_rancher_registration_token_test.go @@ -0,0 +1,28 @@ +package rancher + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccRancherRegistrationToken_importBasic(t *testing.T) { + resourceName := "rancher_registration_token.foo" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckRancherRegistrationTokenDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccRancherRegistrationTokenConfig, + }, + + resource.TestStep{ + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/builtin/providers/rancher/import_rancher_registry_credential_test.go b/builtin/providers/rancher/import_rancher_registry_credential_test.go new file mode 100644 index 000000000000..9e292880398c --- /dev/null +++ b/builtin/providers/rancher/import_rancher_registry_credential_test.go @@ -0,0 +1,30 @@ +package rancher + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccRancherRegistryCredential_importBasic(t *testing.T) { + resourceName := "rancher_registry_credential.foo" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckRancherRegistryCredentialDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccRancherRegistryCredentialConfig, + }, + + resource.TestStep{ + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "secret_value"}, + }, + }, + }) +} diff --git a/builtin/providers/rancher/import_rancher_registry_test.go b/builtin/providers/rancher/import_rancher_registry_test.go new file mode 100644 index 000000000000..f1c9db86c3e0 --- /dev/null +++ b/builtin/providers/rancher/import_rancher_registry_test.go @@ -0,0 +1,28 @@ +package rancher + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccRancherRegistry_importBasic(t *testing.T) { + resourceName := "rancher_registry.foo" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckRancherRegistryDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccRancherRegistryConfig, + }, + + resource.TestStep{ + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/builtin/providers/rancher/import_rancher_stack_test.go b/builtin/providers/rancher/import_rancher_stack_test.go new file mode 100644 index 000000000000..029b8c4dd086 --- /dev/null +++ b/builtin/providers/rancher/import_rancher_stack_test.go @@ -0,0 +1,28 @@ +package rancher + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccRancherStack_importBasic(t *testing.T) { + resourceName := "rancher_stack.foo" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckRancherStackDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccRancherStackConfig, + }, + + resource.TestStep{ + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/builtin/providers/rancher/provider.go b/builtin/providers/rancher/provider.go index 2039f2af6df1..e553b649ef03 100644 --- a/builtin/providers/rancher/provider.go +++ b/builtin/providers/rancher/provider.go @@ -3,7 +3,6 @@ package rancher import ( "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" - // "github.com/rancher/go-rancher/client" ) // Provider returns a terraform.ResourceProvider. @@ -18,14 +17,14 @@ func Provider() terraform.ResourceProvider { }, "access_key": &schema.Schema{ Type: schema.TypeString, - Required: true, - DefaultFunc: schema.EnvDefaultFunc("RANCHER_ACCESS_KEY", nil), + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("RANCHER_ACCESS_KEY", ""), Description: descriptions["access_key"], }, "secret_key": &schema.Schema{ Type: schema.TypeString, - Required: true, - DefaultFunc: schema.EnvDefaultFunc("RANCHER_SECRET_KEY", nil), + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("RANCHER_SECRET_KEY", ""), Description: descriptions["secret_key"], }, }, diff --git a/builtin/providers/rancher/provider_test.go b/builtin/providers/rancher/provider_test.go index 738015a78c80..b79e340c272f 100644 --- a/builtin/providers/rancher/provider_test.go +++ b/builtin/providers/rancher/provider_test.go @@ -32,12 +32,4 @@ func testAccPreCheck(t *testing.T) { if v := os.Getenv("RANCHER_URL"); v == "" { t.Fatal("RANCHER_URL must be set for acceptance tests") } - - if v := os.Getenv("RANCHER_ACCESS_KEY"); v == "" { - t.Fatal("RANCHER_ACCESS_KEY must be set for acceptance tests") - } - - if v := os.Getenv("RANCHER_SECRET_KEY"); v == "" { - t.Fatal("RANCHER_SECRET_KEY must be set for acceptance tests") - } } diff --git a/builtin/providers/rancher/resource_rancher_environment.go b/builtin/providers/rancher/resource_rancher_environment.go index 1e0a247f75fe..8bd7634be49c 100644 --- a/builtin/providers/rancher/resource_rancher_environment.go +++ b/builtin/providers/rancher/resource_rancher_environment.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" - rancher "github.com/rancher/go-rancher/client" + rancherClient "github.com/rancher/go-rancher/client" ) func resourceRancherEnvironment() *schema.Resource { @@ -58,11 +58,25 @@ func resourceRancherEnvironmentCreate(d *schema.ResourceData, meta interface{}) setOrchestrationFields(orchestration, data) - var newEnv rancher.Project + var newEnv rancherClient.Project if err := client.Create("project", data, &newEnv); err != nil { return err } + stateConf := &resource.StateChangeConf{ + Pending: []string{"active", "removed", "removing"}, + Target: []string{"active"}, + Refresh: EnvironmentStateRefreshFunc(client, newEnv.Id), + Timeout: 10 * time.Minute, + Delay: 1 * time.Second, + MinTimeout: 3 * time.Second, + } + _, waitErr := stateConf.WaitForState() + if waitErr != nil { + return fmt.Errorf( + "Error waiting for environment (%s) to be created: %s", newEnv.Id, waitErr) + } + d.SetId(newEnv.Id) log.Printf("[INFO] Environment ID: %s", d.Id()) @@ -101,7 +115,7 @@ func resourceRancherEnvironmentUpdate(d *schema.ResourceData, meta interface{}) setOrchestrationFields(orchestration, data) - var newEnv rancher.Project + var newEnv rancherClient.Project env, err := client.Project.ById(d.Id()) if err != nil { return err diff --git a/builtin/providers/rancher/resource_rancher_environment_test.go b/builtin/providers/rancher/resource_rancher_environment_test.go index 96ba9ca74282..d71fd35d5782 100644 --- a/builtin/providers/rancher/resource_rancher_environment_test.go +++ b/builtin/providers/rancher/resource_rancher_environment_test.go @@ -6,11 +6,11 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - rancher "github.com/rancher/go-rancher/client" + rancherClient "github.com/rancher/go-rancher/client" ) func TestAccRancherEnvironment(t *testing.T) { - var environment rancher.Project + var environment rancherClient.Project resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -21,21 +21,25 @@ func TestAccRancherEnvironment(t *testing.T) { Config: testAccRancherEnvironmentConfig, Check: resource.ComposeTestCheckFunc( testAccCheckRancherEnvironmentExists("rancher_environment.foo", &environment), - testAccCheckRancherEnvironmentAttributes(&environment, "foo", "Terraform acc test group", "cattle"), + 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.TestStep{ Config: testAccRancherEnvironmentUpdateConfig, Check: resource.ComposeTestCheckFunc( testAccCheckRancherEnvironmentExists("rancher_environment.foo", &environment), - testAccCheckRancherEnvironmentAttributes(&environment, "foo2", "Terraform acc test group - updated", "swarm"), + 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"), ), }, }, }) } -func testAccCheckRancherEnvironmentExists(n string, env *rancher.Project) resource.TestCheckFunc { +func testAccCheckRancherEnvironmentExists(n string, env *rancherClient.Project) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -64,25 +68,6 @@ func testAccCheckRancherEnvironmentExists(n string, env *rancher.Project) resour } } -func testAccCheckRancherEnvironmentAttributes(env *rancher.Project, envName string, envDesc string, envOrchestration string) resource.TestCheckFunc { - return func(s *terraform.State) error { - if env.Name != envName { - return fmt.Errorf("Bad name: %s shoud be: %s", env.Name, envName) - } - - if env.Description != envDesc { - return fmt.Errorf("Bad description: %s shoud be: %s", env.Description, envDesc) - } - - orchestration := GetActiveOrchestration(env) - if orchestration != envOrchestration { - return fmt.Errorf("Bad orchestraion: %s shoud be: %s", orchestration, envOrchestration) - } - - return nil - } -} - func testAccCheckRancherEnvironmentDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*Config) diff --git a/builtin/providers/rancher/resource_rancher_registration_token.go b/builtin/providers/rancher/resource_rancher_registration_token.go index e16354c99ccf..dcf10b77ee69 100644 --- a/builtin/providers/rancher/resource_rancher_registration_token.go +++ b/builtin/providers/rancher/resource_rancher_registration_token.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" - rancher "github.com/rancher/go-rancher/client" + rancherClient "github.com/rancher/go-rancher/client" ) func resourceRancherRegistrationToken() *schema.Resource { @@ -66,11 +66,25 @@ func resourceRancherRegistrationTokenCreate(d *schema.ResourceData, meta interfa "description": &description, } - var newRegT rancher.RegistrationToken + var newRegT rancherClient.RegistrationToken if err := client.Create("registrationToken", data, &newRegT); err != nil { return err } + stateConf := &resource.StateChangeConf{ + Pending: []string{"active", "removed", "removing"}, + Target: []string{"active"}, + Refresh: RegistrationTokenStateRefreshFunc(client, newRegT.Id), + Timeout: 10 * time.Minute, + Delay: 1 * time.Second, + MinTimeout: 3 * time.Second, + } + _, waitErr := stateConf.WaitForState() + if waitErr != nil { + return fmt.Errorf( + "Error waiting for registration token (%s) to be created: %s", newRegT.Id, waitErr) + } + d.SetId(newRegT.Id) log.Printf("[INFO] RegistrationToken ID: %s", d.Id()) @@ -79,10 +93,7 @@ func resourceRancherRegistrationTokenCreate(d *schema.ResourceData, meta interfa func resourceRancherRegistrationTokenRead(d *schema.ResourceData, meta interface{}) error { log.Printf("[INFO] Refreshing RegistrationToken: %s", d.Id()) - client, err := meta.(*Config).EnvironmentClient(d.Get("environment_id").(string)) - if err != nil { - return err - } + client := meta.(*Config) regT, err := client.RegistrationToken.ById(d.Id()) if err != nil { @@ -95,6 +106,7 @@ func resourceRancherRegistrationTokenRead(d *schema.ResourceData, meta interface d.Set("name", regT.Name) d.Set("token", regT.Token) d.Set("registration_url", regT.RegistrationUrl) + d.Set("environment_id", regT.AccountId) return nil } @@ -113,7 +125,7 @@ func resourceRancherRegistrationTokenDelete(d *schema.ResourceData, meta interfa } // Step 1: Deactivate - if _, err := client.RegistrationToken.ActionDeactivate(regT); err != nil { + if _, e := client.RegistrationToken.ActionDeactivate(regT); e != nil { return fmt.Errorf("Error deactivating RegistrationToken: %s", err) } @@ -168,7 +180,7 @@ func resourceRancherRegistrationTokenDelete(d *schema.ResourceData, meta interfa // RegistrationTokenStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch // a Rancher RegistrationToken. -func RegistrationTokenStateRefreshFunc(client *rancher.RancherClient, regTID string) resource.StateRefreshFunc { +func RegistrationTokenStateRefreshFunc(client *rancherClient.RancherClient, regTID string) resource.StateRefreshFunc { return func() (interface{}, string, error) { regT, err := client.RegistrationToken.ById(regTID) diff --git a/builtin/providers/rancher/resource_rancher_registration_token_test.go b/builtin/providers/rancher/resource_rancher_registration_token_test.go index d4cce08dd153..d92ce2bfa282 100644 --- a/builtin/providers/rancher/resource_rancher_registration_token_test.go +++ b/builtin/providers/rancher/resource_rancher_registration_token_test.go @@ -6,11 +6,11 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - rancher "github.com/rancher/go-rancher/client" + rancherClient "github.com/rancher/go-rancher/client" ) func TestAccRancherRegistrationToken(t *testing.T) { - var registrationToken rancher.RegistrationToken + var registrationToken rancherClient.RegistrationToken resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -21,14 +21,27 @@ func TestAccRancherRegistrationToken(t *testing.T) { Config: testAccRancherRegistrationTokenConfig, Check: resource.ComposeTestCheckFunc( testAccCheckRancherRegistrationTokenExists("rancher_registration_token.foo", ®istrationToken), - testAccCheckRancherRegistrationTokenAttributes(®istrationToken, "foo", "Terraform acc test group"), + resource.TestCheckResourceAttr( + "rancher_registration_token.foo", "name", "foo"), + resource.TestCheckResourceAttr( + "rancher_registration_token.foo", "description", "Terraform acc test group"), + ), + }, + resource.TestStep{ + Config: testAccRancherRegistrationTokenUpdateConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckRancherRegistrationTokenExists("rancher_registration_token.foo", ®istrationToken), + resource.TestCheckResourceAttr( + "rancher_registration_token.foo", "name", "foo-u"), + resource.TestCheckResourceAttr( + "rancher_registration_token.foo", "description", "Terraform acc test group-u"), ), }, }, }) } -func testAccCheckRancherRegistrationTokenExists(n string, regT *rancher.RegistrationToken) resource.TestCheckFunc { +func testAccCheckRancherRegistrationTokenExists(n string, regT *rancherClient.RegistrationToken) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -57,20 +70,6 @@ func testAccCheckRancherRegistrationTokenExists(n string, regT *rancher.Registra } } -func testAccCheckRancherRegistrationTokenAttributes(regT *rancher.RegistrationToken, regTName string, regTDesc string) resource.TestCheckFunc { - return func(s *terraform.State) error { - if regT.Name != regTName { - return fmt.Errorf("Bad name: %s shoud be: %s", regT.Name, regTName) - } - - if regT.Description != regTDesc { - return fmt.Errorf("Bad description: %s shoud be: %s", regT.Description, regTDesc) - } - - return nil - } -} - func testAccCheckRancherRegistrationTokenDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*Config) @@ -91,13 +90,28 @@ func testAccCheckRancherRegistrationTokenDestroy(s *terraform.State) error { return nil } return nil - return nil } const testAccRancherRegistrationTokenConfig = ` +resource "rancher_environment" "foo" { + name = "foo" +} + resource "rancher_registration_token" "foo" { name = "foo" description = "Terraform acc test group" - environment_id = "1a5" + environment_id = "${rancher_environment.foo.id}" +} +` + +const testAccRancherRegistrationTokenUpdateConfig = ` +resource "rancher_environment" "foo" { + name = "foo" +} + +resource "rancher_registration_token" "foo" { + name = "foo-u" + description = "Terraform acc test group-u" + environment_id = "${rancher_environment.foo.id}" } ` diff --git a/builtin/providers/rancher/resource_rancher_registry.go b/builtin/providers/rancher/resource_rancher_registry.go index f6890ed621e2..99fef3b01adb 100644 --- a/builtin/providers/rancher/resource_rancher_registry.go +++ b/builtin/providers/rancher/resource_rancher_registry.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" - rancher "github.com/rancher/go-rancher/client" + rancherClient "github.com/rancher/go-rancher/client" ) func resourceRancherRegistry() *schema.Resource { @@ -58,7 +58,7 @@ func resourceRancherRegistryCreate(d *schema.ResourceData, meta interface{}) err description := d.Get("description").(string) serverAddress := d.Get("server_address").(string) - registry := rancher.Registry{ + registry := rancherClient.Registry{ Name: name, Description: description, ServerAddress: serverAddress, @@ -68,6 +68,20 @@ func resourceRancherRegistryCreate(d *schema.ResourceData, meta interface{}) err return err } + stateConf := &resource.StateChangeConf{ + Pending: []string{"active", "removed", "removing"}, + Target: []string{"active"}, + Refresh: RegistryStateRefreshFunc(client, newRegistry.Id), + Timeout: 10 * time.Minute, + Delay: 1 * time.Second, + MinTimeout: 3 * time.Second, + } + _, waitErr := stateConf.WaitForState() + if waitErr != nil { + return fmt.Errorf( + "Error waiting for registry (%s) to be created: %s", newRegistry.Id, waitErr) + } + d.SetId(newRegistry.Id) log.Printf("[INFO] Registry ID: %s", d.Id()) @@ -76,21 +90,19 @@ func resourceRancherRegistryCreate(d *schema.ResourceData, meta interface{}) err func resourceRancherRegistryRead(d *schema.ResourceData, meta interface{}) error { log.Printf("[INFO] Refreshing Registry: %s", d.Id()) - client, err := meta.(*Config).EnvironmentClient(d.Get("environment_id").(string)) - if err != nil { - return err - } + client := meta.(*Config) - env, err := client.Registry.ById(d.Id()) + registry, err := client.Registry.ById(d.Id()) if err != nil { return err } - log.Printf("[INFO] Registry Name: %s", env.Name) + log.Printf("[INFO] Registry Name: %s", registry.Name) - d.Set("description", env.Description) - d.Set("name", env.Name) - d.Set("server_address", env.ServerAddress) + d.Set("description", registry.Description) + d.Set("name", registry.Name) + d.Set("server_address", registry.ServerAddress) + d.Set("environment_id", registry.AccountId) return nil } @@ -130,7 +142,7 @@ func resourceRancherRegistryDelete(d *schema.ResourceData, meta interface{}) err } // Step 1: Deactivate - if _, err := client.Registry.ActionDeactivate(reg); err != nil { + if _, e := client.Registry.ActionDeactivate(reg); e != nil { return fmt.Errorf("Error deactivating Registry: %s", err) } @@ -185,7 +197,7 @@ func resourceRancherRegistryDelete(d *schema.ResourceData, meta interface{}) err // RegistryStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch // a Rancher Environment. -func RegistryStateRefreshFunc(client *rancher.RancherClient, registryID string) resource.StateRefreshFunc { +func RegistryStateRefreshFunc(client *rancherClient.RancherClient, registryID string) resource.StateRefreshFunc { return func() (interface{}, string, error) { env, err := client.Registry.ById(registryID) diff --git a/builtin/providers/rancher/resource_rancher_registry_credential.go b/builtin/providers/rancher/resource_rancher_registry_credential.go index fb108a82ae54..48ae4bfaa8c6 100644 --- a/builtin/providers/rancher/resource_rancher_registry_credential.go +++ b/builtin/providers/rancher/resource_rancher_registry_credential.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" - rancher "github.com/rancher/go-rancher/client" + rancherClient "github.com/rancher/go-rancher/client" ) func resourceRancherRegistryCredential() *schema.Resource { @@ -69,7 +69,7 @@ func resourceRancherRegistryCredentialCreate(d *schema.ResourceData, meta interf secretValue := d.Get("secret_value").(string) registryID := d.Get("registry_id").(string) - registryCred := rancher.RegistryCredential{ + registryCred := rancherClient.RegistryCredential{ Name: name, Description: description, Email: email, @@ -82,6 +82,20 @@ func resourceRancherRegistryCredentialCreate(d *schema.ResourceData, meta interf return err } + stateConf := &resource.StateChangeConf{ + Pending: []string{"active", "removed", "removing"}, + Target: []string{"active"}, + Refresh: RegistryCredentialStateRefreshFunc(client, newRegistryCredential.Id), + Timeout: 10 * time.Minute, + Delay: 1 * time.Second, + MinTimeout: 3 * time.Second, + } + _, waitErr := stateConf.WaitForState() + if waitErr != nil { + return fmt.Errorf( + "Error waiting for registry credential (%s) to be created: %s", newRegistryCredential.Id, waitErr) + } + d.SetId(newRegistryCredential.Id) log.Printf("[INFO] RegistryCredential ID: %s", d.Id()) @@ -90,22 +104,20 @@ func resourceRancherRegistryCredentialCreate(d *schema.ResourceData, meta interf func resourceRancherRegistryCredentialRead(d *schema.ResourceData, meta interface{}) error { log.Printf("[INFO] Refreshing RegistryCredential: %s", d.Id()) - client, err := meta.(*Config).RegistryClient(d.Get("registry_id").(string)) - if err != nil { - return err - } + client := meta.(*Config) - env, err := client.RegistryCredential.ById(d.Id()) + registryCred, err := client.RegistryCredential.ById(d.Id()) if err != nil { return err } - log.Printf("[INFO] RegistryCredential Name: %s", env.Name) + log.Printf("[INFO] RegistryCredential Name: %s", registryCred.Name) - d.Set("description", env.Description) - d.Set("name", env.Name) - d.Set("email", env.Email) - d.Set("public_value", env.PublicValue) + d.Set("description", registryCred.Description) + d.Set("name", registryCred.Name) + d.Set("email", registryCred.Email) + d.Set("public_value", registryCred.PublicValue) + d.Set("registry_id", registryCred.RegistryId) return nil } @@ -152,7 +164,7 @@ func resourceRancherRegistryCredentialDelete(d *schema.ResourceData, meta interf } // Step 1: Deactivate - if _, err := client.RegistryCredential.ActionDeactivate(reg); err != nil { + if _, e := client.RegistryCredential.ActionDeactivate(reg); e != nil { return fmt.Errorf("Error deactivating RegistryCredential: %s", err) } @@ -207,7 +219,7 @@ func resourceRancherRegistryCredentialDelete(d *schema.ResourceData, meta interf // RegistryCredentialStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch // a Rancher Environment. -func RegistryCredentialStateRefreshFunc(client *rancher.RancherClient, registryCredID string) resource.StateRefreshFunc { +func RegistryCredentialStateRefreshFunc(client *rancherClient.RancherClient, registryCredID string) resource.StateRefreshFunc { return func() (interface{}, string, error) { regC, err := client.RegistryCredential.ById(registryCredID) diff --git a/builtin/providers/rancher/resource_rancher_registry_credential_test.go b/builtin/providers/rancher/resource_rancher_registry_credential_test.go index e3362d351d20..b5f859f4f047 100644 --- a/builtin/providers/rancher/resource_rancher_registry_credential_test.go +++ b/builtin/providers/rancher/resource_rancher_registry_credential_test.go @@ -6,11 +6,11 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - rancher "github.com/rancher/go-rancher/client" + rancherClient "github.com/rancher/go-rancher/client" ) func TestAccRancherRegistryCredential(t *testing.T) { - var registry rancher.RegistryCredential + var registry rancherClient.RegistryCredential resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -21,21 +21,25 @@ func TestAccRancherRegistryCredential(t *testing.T) { Config: testAccRancherRegistryCredentialConfig, Check: resource.ComposeTestCheckFunc( testAccCheckRancherRegistryCredentialExists("rancher_registry_credential.foo", ®istry), - testAccCheckRancherRegistryCredentialAttributes(®istry, "foo", "registry credential test", "user"), + resource.TestCheckResourceAttr("rancher_registry_credential.foo", "name", "foo"), + resource.TestCheckResourceAttr("rancher_registry_credential.foo", "description", "registry credential test"), + resource.TestCheckResourceAttr("rancher_registry_credential.foo", "public_value", "user"), ), }, resource.TestStep{ Config: testAccRancherRegistryCredentialUpdateConfig, Check: resource.ComposeTestCheckFunc( testAccCheckRancherRegistryCredentialExists("rancher_registry_credential.foo", ®istry), - testAccCheckRancherRegistryCredentialAttributes(®istry, "foo2", "registry credential test - updated", "user2"), + resource.TestCheckResourceAttr("rancher_registry_credential.foo", "name", "foo2"), + resource.TestCheckResourceAttr("rancher_registry_credential.foo", "description", "registry credential test - updated"), + resource.TestCheckResourceAttr("rancher_registry_credential.foo", "public_value", "user2"), ), }, }, }) } -func testAccCheckRancherRegistryCredentialExists(n string, reg *rancher.RegistryCredential) resource.TestCheckFunc { +func testAccCheckRancherRegistryCredentialExists(n string, reg *rancherClient.RegistryCredential) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -64,24 +68,6 @@ func testAccCheckRancherRegistryCredentialExists(n string, reg *rancher.Registry } } -func testAccCheckRancherRegistryCredentialAttributes(reg *rancher.RegistryCredential, regName string, regDesc string, regPublic string) resource.TestCheckFunc { - return func(s *terraform.State) error { - if reg.Name != regName { - return fmt.Errorf("Bad name: %s shoud be: %s", reg.Name, regName) - } - - if reg.Description != regDesc { - return fmt.Errorf("Bad description: %s shoud be: %s", reg.Description, regDesc) - } - - if reg.PublicValue != regPublic { - return fmt.Errorf("Bad public_value: %s shoud be: %s", reg.PublicValue, regPublic) - } - - return nil - } -} - func testAccCheckRancherRegistryCredentialDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*Config) @@ -105,11 +91,15 @@ func testAccCheckRancherRegistryCredentialDestroy(s *terraform.State) error { } const testAccRancherRegistryCredentialConfig = ` +resource "rancher_environment" "foo" { + name = "foo" +} + resource "rancher_registry" "foo" { name = "foo" description = "registry test" server_address = "http://bar.com:8080" - environment_id = "1a5" + environment_id = "${rancher_environment.foo.id}" } resource "rancher_registry_credential" "foo" { @@ -123,11 +113,15 @@ resource "rancher_registry_credential" "foo" { ` const testAccRancherRegistryCredentialUpdateConfig = ` +resource "rancher_environment" "foo" { + name = "foo" +} + resource "rancher_registry" "foo" { name = "foo" description = "registry test" server_address = "http://bar.com:8080" - environment_id = "1a5" + environment_id = "${rancher_environment.foo.id}" } resource "rancher_registry_credential" "foo" { diff --git a/builtin/providers/rancher/resource_rancher_registry_test.go b/builtin/providers/rancher/resource_rancher_registry_test.go index 71b01f3264eb..308dc20f9192 100644 --- a/builtin/providers/rancher/resource_rancher_registry_test.go +++ b/builtin/providers/rancher/resource_rancher_registry_test.go @@ -6,11 +6,11 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - rancher "github.com/rancher/go-rancher/client" + rancherClient "github.com/rancher/go-rancher/client" ) func TestAccRancherRegistry(t *testing.T) { - var registry rancher.Registry + var registry rancherClient.Registry resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -21,28 +21,34 @@ func TestAccRancherRegistry(t *testing.T) { Config: testAccRancherRegistryConfig, Check: resource.ComposeTestCheckFunc( testAccCheckRancherRegistryExists("rancher_registry.foo", ®istry), - testAccCheckRancherRegistryAttributes(®istry, "foo", "registry test", "http://foo.com:8080"), + resource.TestCheckResourceAttr("rancher_registry.foo", "name", "foo"), + resource.TestCheckResourceAttr("rancher_registry.foo", "description", "registry test"), + resource.TestCheckResourceAttr("rancher_registry.foo", "server_address", "http://foo.com:8080"), ), }, resource.TestStep{ Config: testAccRancherRegistryUpdateConfig, Check: resource.ComposeTestCheckFunc( testAccCheckRancherRegistryExists("rancher_registry.foo", ®istry), - testAccCheckRancherRegistryAttributes(®istry, "foo2", "registry test - updated", "http://foo.updated.com:8080"), + resource.TestCheckResourceAttr("rancher_registry.foo", "name", "foo2"), + resource.TestCheckResourceAttr("rancher_registry.foo", "description", "registry test - updated"), + resource.TestCheckResourceAttr("rancher_registry.foo", "server_address", "http://foo.updated.com:8080"), ), }, resource.TestStep{ Config: testAccRancherRegistryRecreateConfig, Check: resource.ComposeTestCheckFunc( testAccCheckRancherRegistryExists("rancher_registry.foo", ®istry), - testAccCheckRancherRegistryAttributes(®istry, "foo", "registry test", "http://foo.com:8080"), + resource.TestCheckResourceAttr("rancher_registry.foo", "name", "foo"), + resource.TestCheckResourceAttr("rancher_registry.foo", "description", "registry test"), + resource.TestCheckResourceAttr("rancher_registry.foo", "server_address", "http://foo.com:8080"), ), }, }, }) } -func testAccCheckRancherRegistryExists(n string, reg *rancher.Registry) resource.TestCheckFunc { +func testAccCheckRancherRegistryExists(n string, reg *rancherClient.Registry) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -71,24 +77,6 @@ func testAccCheckRancherRegistryExists(n string, reg *rancher.Registry) resource } } -func testAccCheckRancherRegistryAttributes(reg *rancher.Registry, regName string, regDesc string, regServerAddress string) resource.TestCheckFunc { - return func(s *terraform.State) error { - if reg.Name != regName { - return fmt.Errorf("Bad name: %s shoud be: %s", reg.Name, regName) - } - - if reg.Description != regDesc { - return fmt.Errorf("Bad description: %s shoud be: %s", reg.Description, regDesc) - } - - if reg.ServerAddress != regServerAddress { - return fmt.Errorf("Bad server_address: %s shoud be: %s", reg.ServerAddress, regServerAddress) - } - - return nil - } -} - func testAccCheckRancherRegistryDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*Config) @@ -112,11 +100,16 @@ func testAccCheckRancherRegistryDestroy(s *terraform.State) error { } const testAccRancherRegistryConfig = ` +resource "rancher_environment" "foo_registry" { + name = "registry test" + description = "environment to test registries" +} + resource "rancher_registry" "foo" { name = "foo" description = "registry test" server_address = "http://foo.com:8080" - environment_id = "1a5" + environment_id = "${rancher_environment.foo_registry.id}" } ` @@ -126,11 +119,6 @@ const testAccRancherRegistryUpdateConfig = ` description = "environment to test registries" } - resource "rancher_environment" "foo_registry2" { - name = "alternative registry test" - description = "other environment to test registries" - } - resource "rancher_registry" "foo" { name = "foo2" description = "registry test - updated" @@ -154,6 +142,6 @@ const testAccRancherRegistryRecreateConfig = ` name = "foo" description = "registry test" server_address = "http://foo.com:8080" - environment_id = "${rancher_environment.foo_registry.id}" + environment_id = "${rancher_environment.foo_registry2.id}" } ` diff --git a/builtin/providers/rancher/resource_rancher_stack.go b/builtin/providers/rancher/resource_rancher_stack.go index e62b61497260..e8e66d840dc8 100644 --- a/builtin/providers/rancher/resource_rancher_stack.go +++ b/builtin/providers/rancher/resource_rancher_stack.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" - rancher "github.com/rancher/go-rancher/client" + rancherClient "github.com/rancher/go-rancher/client" ) func resourceRancherStack() *schema.Resource { @@ -81,11 +81,25 @@ func resourceRancherStackCreate(d *schema.ResourceData, meta interface{}) error return err } - var newStack rancher.Environment + var newStack rancherClient.Environment if err := client.Create("environment", data, &newStack); err != nil { return err } + stateConf := &resource.StateChangeConf{ + Pending: []string{"activating", "active", "removed", "removing"}, + Target: []string{"active"}, + Refresh: StackStateRefreshFunc(client, newStack.Id), + Timeout: 10 * time.Minute, + Delay: 1 * time.Second, + MinTimeout: 3 * time.Second, + } + _, waitErr := stateConf.WaitForState() + if waitErr != nil { + return fmt.Errorf( + "Error waiting for stack (%s) to be created: %s", newStack.Id, waitErr) + } + d.SetId(newStack.Id) log.Printf("[INFO] Stack ID: %s", d.Id()) @@ -94,10 +108,7 @@ func resourceRancherStackCreate(d *schema.ResourceData, meta interface{}) error func resourceRancherStackRead(d *schema.ResourceData, meta interface{}) error { log.Printf("[INFO] Refreshing Stack: %s", d.Id()) - client, err := meta.(*Config).EnvironmentClient(d.Get("environment_id").(string)) - if err != nil { - return err - } + client := meta.(*Config) stack, err := client.Environment.ById(d.Id()) if err != nil { @@ -110,6 +121,7 @@ func resourceRancherStackRead(d *schema.ResourceData, meta interface{}) error { d.Set("name", stack.Name) d.Set("docker_compose", stack.DockerCompose) d.Set("rancher_compose", stack.RancherCompose) + d.Set("environment_id", stack.AccountId) d.Set("environment", stack.Environment) if stack.ExternalId == "" { @@ -144,7 +156,7 @@ func resourceRancherStackUpdate(d *schema.ResourceData, meta interface{}) error // TODO: upgrade stack if docker_compose, rancher_compose or environment have changed - var newStack rancher.Environment + var newStack rancherClient.Environment stack, err := client.Environment.ById(d.Id()) if err != nil { return err @@ -197,7 +209,7 @@ func resourceRancherStackDelete(d *schema.ResourceData, meta interface{}) error // StackStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch // a Rancher Stack. -func StackStateRefreshFunc(client *rancher.RancherClient, stackID string) resource.StateRefreshFunc { +func StackStateRefreshFunc(client *rancherClient.RancherClient, stackID string) resource.StateRefreshFunc { return func() (interface{}, string, error) { stack, err := client.Environment.ById(stackID) diff --git a/builtin/providers/rancher/resource_rancher_stack_test.go b/builtin/providers/rancher/resource_rancher_stack_test.go index 5f60dfaae477..2c2c5cab138e 100644 --- a/builtin/providers/rancher/resource_rancher_stack_test.go +++ b/builtin/providers/rancher/resource_rancher_stack_test.go @@ -6,11 +6,11 @@ import ( "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - rancher "github.com/rancher/go-rancher/client" + rancherClient "github.com/rancher/go-rancher/client" ) func TestAccRancherStack(t *testing.T) { - var stack rancher.Environment + var stack rancherClient.Environment resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -21,35 +21,56 @@ func TestAccRancherStack(t *testing.T) { Config: testAccRancherStackConfig, Check: resource.ComposeTestCheckFunc( testAccCheckRancherStackExists("rancher_stack.foo", &stack), - testAccCheckRancherStackAttributes(&stack, "foo", "Terraform acc test group", "", "", "", emptyEnvironment, false), + resource.TestCheckResourceAttr("rancher_stack.foo", "name", "foo"), + resource.TestCheckResourceAttr("rancher_stack.foo", "description", "Terraform acc test group"), + resource.TestCheckResourceAttr("rancher_stack.foo", "catalog_id", ""), + resource.TestCheckResourceAttr("rancher_stack.foo", "docker_compose", ""), + resource.TestCheckResourceAttr("rancher_stack.foo", "rancher_compose", ""), + testAccCheckRancherStackAttributes(&stack, emptyEnvironment, false), ), }, resource.TestStep{ Config: testAccRancherStackUpdateConfig, Check: resource.ComposeTestCheckFunc( testAccCheckRancherStackExists("rancher_stack.foo", &stack), - testAccCheckRancherStackAttributes(&stack, "foo2", "Terraform acc test group - updated", "", "", "", emptyEnvironment, false), + resource.TestCheckResourceAttr("rancher_stack.foo", "name", "foo2"), + resource.TestCheckResourceAttr("rancher_stack.foo", "description", "Terraform acc test group - updated"), + resource.TestCheckResourceAttr("rancher_stack.foo", "catalog_id", ""), + resource.TestCheckResourceAttr("rancher_stack.foo", "docker_compose", ""), + resource.TestCheckResourceAttr("rancher_stack.foo", "rancher_compose", ""), + testAccCheckRancherStackAttributes(&stack, emptyEnvironment, false), ), }, resource.TestStep{ Config: testAccRancherStackComposeConfig, Check: resource.ComposeTestCheckFunc( testAccCheckRancherStackExists("rancher_stack.compose", &stack), - testAccCheckRancherStackAttributes(&stack, "compose", "Terraform acc test group - compose", "", "web: { image: nginx }", "web: { scale: 1 }", emptyEnvironment, true), + resource.TestCheckResourceAttr("rancher_stack.compose", "name", "compose"), + resource.TestCheckResourceAttr("rancher_stack.compose", "description", "Terraform acc test group - compose"), + resource.TestCheckResourceAttr("rancher_stack.compose", "catalog_id", ""), + resource.TestCheckResourceAttr("rancher_stack.compose", "docker_compose", "web: { image: nginx }"), + resource.TestCheckResourceAttr("rancher_stack.compose", "rancher_compose", "web: { scale: 1 }"), + testAccCheckRancherStackAttributes(&stack, emptyEnvironment, false), ), }, resource.TestStep{ Config: testAccRancherStackSystemCatalogConfig, Check: resource.ComposeTestCheckFunc( testAccCheckRancherStackExists("rancher_stack.catalog", &stack), - testAccCheckRancherStackAttributes(&stack, "catalog", "Terraform acc test group - catalog", "system-catalog://library:route53:7", route53DockerCompose, route53RancherCompose, route53Environment, false), + resource.TestCheckResourceAttr("rancher_stack.catalog", "name", "catalog"), + resource.TestCheckResourceAttr("rancher_stack.catalog", "description", "Terraform acc test group - catalog"), + resource.TestCheckResourceAttr("rancher_stack.catalog", "catalog_id", "library:route53:7"), + resource.TestCheckResourceAttr("rancher_stack.catalog", "scope", "system"), + resource.TestCheckResourceAttr("rancher_stack.catalog", "docker_compose", route53DockerCompose), + resource.TestCheckResourceAttr("rancher_stack.catalog", "rancher_compose", route53RancherCompose), + testAccCheckRancherStackAttributes(&stack, route53Environment, false), ), }, }, }) } -func testAccCheckRancherStackExists(n string, stack *rancher.Environment) resource.TestCheckFunc { +func testAccCheckRancherStackExists(n string, stack *rancherClient.Environment) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -78,27 +99,8 @@ func testAccCheckRancherStackExists(n string, stack *rancher.Environment) resour } } -func testAccCheckRancherStackAttributes(stack *rancher.Environment, stackName string, stackDesc string, externalID string, dockerCompose string, rancherCompose string, environment map[string]string, startOnCreate bool) resource.TestCheckFunc { +func testAccCheckRancherStackAttributes(stack *rancherClient.Environment, environment map[string]string, startOnCreate bool) resource.TestCheckFunc { return func(s *terraform.State) error { - if stack.Name != stackName { - return fmt.Errorf("Bad name: %s should be: %s", stack.Name, stackName) - } - - if stack.Description != stackDesc { - return fmt.Errorf("Bad description: %s should be: %s", stack.Description, stackDesc) - } - - if stack.ExternalId != externalID { - return fmt.Errorf("Bad externalID: %s should be: %s", stack.ExternalId, externalID) - } - - if stack.DockerCompose != dockerCompose { - return fmt.Errorf("Bad dockerCompose: %s should be: %s", stack.DockerCompose, dockerCompose) - } - - if stack.RancherCompose != rancherCompose { - return fmt.Errorf("Bad rancherCompose: %s should be: %s", stack.RancherCompose, rancherCompose) - } if len(stack.Environment) != len(environment) { return fmt.Errorf("Bad environment size: %v should be: %v", len(stack.Environment), environment) @@ -111,7 +113,7 @@ func testAccCheckRancherStackAttributes(stack *rancher.Environment, stackName st } if stack.StartOnCreate != startOnCreate { - return fmt.Errorf("Bad startOnCreate: %s should be: %s", stack.StartOnCreate, startOnCreate) + return fmt.Errorf("Bad startOnCreate: %t should be: %t", stack.StartOnCreate, startOnCreate) } return nil @@ -141,37 +143,52 @@ func testAccCheckRancherStackDestroy(s *terraform.State) error { } const testAccRancherStackConfig = ` +resource "rancher_environment" "foo" { + name = "foo" +} + resource "rancher_stack" "foo" { name = "foo" description = "Terraform acc test group" - environment_id = "1a5" + environment_id = "${rancher_environment.foo.id}" } ` const testAccRancherStackUpdateConfig = ` +resource "rancher_environment" "foo" { + name = "foo" +} + resource "rancher_stack" "foo" { name = "foo2" description = "Terraform acc test group - updated" - environment_id = "1a5" + environment_id = "${rancher_environment.foo.id}" } ` const testAccRancherStackComposeConfig = ` +resource "rancher_environment" "foo" { + name = "foo" +} + resource "rancher_stack" "compose" { name = "compose" description = "Terraform acc test group - compose" - environment_id = "1a5" + environment_id = "${rancher_environment.foo.id}" docker_compose = "web: { image: nginx }" rancher_compose = "web: { scale: 1 }" - start_on_create = true } ` const testAccRancherStackSystemCatalogConfig = ` +resource "rancher_environment" "foo" { + name = "foo" +} + resource "rancher_stack" "catalog" { name = "catalog" description = "Terraform acc test group - catalog" - environment_id = "1a5" + environment_id = "${rancher_environment.foo.id}" catalog_id = "library:route53:7" scope = "system" environment { diff --git a/command/internal_plugin_list.go b/command/internal_plugin_list.go index 077dfecbf1e9..dfa11667b830 100644 --- a/command/internal_plugin_list.go +++ b/command/internal_plugin_list.go @@ -40,6 +40,7 @@ import ( postgresqlprovider "github.com/hashicorp/terraform/builtin/providers/postgresql" powerdnsprovider "github.com/hashicorp/terraform/builtin/providers/powerdns" rabbitmqprovider "github.com/hashicorp/terraform/builtin/providers/rabbitmq" + rancherprovider "github.com/hashicorp/terraform/builtin/providers/rancher" randomprovider "github.com/hashicorp/terraform/builtin/providers/random" rundeckprovider "github.com/hashicorp/terraform/builtin/providers/rundeck" scalewayprovider "github.com/hashicorp/terraform/builtin/providers/scaleway" @@ -97,6 +98,7 @@ var InternalProviders = map[string]plugin.ProviderFunc{ "postgresql": postgresqlprovider.Provider, "powerdns": powerdnsprovider.Provider, "rabbitmq": rabbitmqprovider.Provider, + "rancher": rancherprovider.Provider, "random": randomprovider.Provider, "rundeck": rundeckprovider.Provider, "scaleway": scalewayprovider.Provider, diff --git a/website/source/assets/stylesheets/_docs.scss b/website/source/assets/stylesheets/_docs.scss index ed6ec5cdaf41..51d289b9ee17 100755 --- a/website/source/assets/stylesheets/_docs.scss +++ b/website/source/assets/stylesheets/_docs.scss @@ -40,6 +40,7 @@ body.layout-packet, body.layout-postgresql, body.layout-powerdns, body.layout-rabbitmq, +body.layout-rancher, body.layout-random, body.layout-rundeck, body.layout-scaleway, diff --git a/website/source/docs/providers/rancher/index.html.markdown b/website/source/docs/providers/rancher/index.html.markdown new file mode 100644 index 000000000000..736c1d0870f6 --- /dev/null +++ b/website/source/docs/providers/rancher/index.html.markdown @@ -0,0 +1,33 @@ +--- +layout: "rancher" +page_title: "Provider: Rancher" +sidebar_current: "docs-rancher-index" +description: |- + The Rancher provider is used to interact with Rancher container platforms. +--- + +# Rancher Provider + +The Rancher provider is used to interact with the +resources supported by Rancher. The provider needs to be configured +with the URL of the Rancher server at minimum and API credentials if +access control is enabled on the server. + +## Example Usage + +```hcl +# Configure the Rancher provider +provider "rancher" { + api_url = "http://rancher.my-domain.com:8080" + access_key = "${var.rancher_access_key}" + secret_key = "${var.rancher_secret_key}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `api_url` - (Required) Rancher API url. It must be provided, but it can also be sourced from the `RANCHER_URL` environment variable. +* `access_key` - (Optional) Rancher API access key. It can also be sourced from the `RANCHER_ACCESS_KEY` environment variable. +* `secret_key` - (Optional) Rancher API access key. It can also be sourced from the `RANCHER_SECRET_KEY` environment variable. diff --git a/website/source/docs/providers/rancher/r/environment.html.md b/website/source/docs/providers/rancher/r/environment.html.md new file mode 100644 index 000000000000..2c99016d2f0c --- /dev/null +++ b/website/source/docs/providers/rancher/r/environment.html.md @@ -0,0 +1,47 @@ +--- +layout: "rancher" +page_title: "Rancher: rancher_environment" +sidebar_current: "docs-rancher-resource-environment" +description: |- + Provides a Rancher Environment resource. This can be used to create and manage environments on rancher. +--- + +# rancher\_environment + +Provides a Rancher Environment resource. This can be used to create and manage environments on rancher. + +## Example Usage + +```hcl +# Create a new Rancher environment +resource "rancher_environment" "default" { + name = "staging" + description = "The staging environment" + orchestration = "cattle" +} +``` + +## Argument Reference + +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**. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the environment. +* `name` - The name of the environment. +* `description` - The description of the environment. +* `orchestration` - The orchestration engine for the environment. + +## Import + +Environments can be imported using their Rancher API ID, e.g. + +``` +$ terraform import rancher_environment.dev 1a15 +``` diff --git a/website/source/docs/providers/rancher/r/registration_token.html.markdown b/website/source/docs/providers/rancher/r/registration_token.html.markdown new file mode 100644 index 000000000000..d0b90dcbafc9 --- /dev/null +++ b/website/source/docs/providers/rancher/r/registration_token.html.markdown @@ -0,0 +1,49 @@ +--- +layout: "rancher" +page_title: "Rancher: rancher_registration_token" +sidebar_current: "docs-rancher-resource-registration-token" +description: |- + Provides a Rancher Registration Token resource. This can be used to create registration tokens for rancher environments and retrieve their information. +--- + +# rancher\_registration\_token + +Provides a Rancher Registration Token resource. This can be used to create registration tokens for rancher environments and retrieve their information. + +## Example Usage + +```hcl +# Create a new Rancher registration token +resource "rancher_registration_token" "default" { + name = "staging_token" + description = "Registration token for the staging environment" + environment_id = "${rancher_environment.default.id}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the registration token. +* `description` - (Optional) A registration token description. +* `environment_id` - (Required) The ID of the environment to create the token for. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the environment. +* `name` - The name of the registration token. +* `description` - The description of the registration token. +* `environment_id` - The ID of the environment to create the token for. +* `registration_url` - The URL to use to register new nodes to the environment. +* `token` - The token to use to register new nodes to the environment. + +## Import + +Registration tokens can be imported using their Rancher API ID, e.g. + +``` +$ terraform import rancher_registration_token.dev_token 1c11 +``` diff --git a/website/source/docs/providers/rancher/r/registry.html.markdown b/website/source/docs/providers/rancher/r/registry.html.markdown new file mode 100644 index 000000000000..945cf7d45364 --- /dev/null +++ b/website/source/docs/providers/rancher/r/registry.html.markdown @@ -0,0 +1,50 @@ +--- +layout: "rancher" +page_title: "Rancher: rancher_registry" +sidebar_current: "docs-rancher-resource-registry" +description: |- + Provides a Rancher Registy resource. This can be used to create registries for rancher environments and retrieve their information. +--- + +# rancher\_registry + +Provides a Rancher Registy resource. This can be used to create registries for rancher environments and retrieve their information + +## Example Usage + +```hcl +# Create a new Rancher registry +resource "rancher_registry" "dockerhub" { + name = "dockerhub" + description = "DockerHub Registry" + environment_id = "${rancher_environment.default.id}" + server_address = "index.dockerhub.io" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the registry. +* `description` - (Optional) A registry description. +* `environment_id` - (Required) The ID of the environment to create the registry for. +* `server_address` - (Required) The server address for the registry. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the registry. +* `name` - (Required) The name of the registry. +* `description` - (Optional) The registry description. +* `environment_id` - (Required) The ID of the environment to create the registry for. +* `server_address` - (Required) The server address for the registry. + +## Import + +Registries can be imported using their Rancher API ID, e.g. + +``` +$ terraform import rancher_registry.private_registry 1sp31 +``` diff --git a/website/source/docs/providers/rancher/r/registry_credential.html.markdown b/website/source/docs/providers/rancher/r/registry_credential.html.markdown new file mode 100644 index 000000000000..19bca11bae8d --- /dev/null +++ b/website/source/docs/providers/rancher/r/registry_credential.html.markdown @@ -0,0 +1,56 @@ +--- +layout: "rancher" +page_title: "Rancher: rancher_registry_credential" +sidebar_current: "docs-rancher-resource-registry-credential" +description: |- + Provides a Rancher Registy Credential resource. This can be used to create registry credentials for rancher environments and retrieve their information. +--- + +# rancher\_registry\_credential + +Provides a Rancher Registy Credential resource. This can be used to create registry credentials for rancher environments and retrieve their information. + +## Example Usage + +```hcl +# Create a new Rancher registry +resource "rancher_registry_credential" "dockerhub" { + name = "dockerhub" + description = "DockerHub Registry Credential" + registry_id = "${rancher_registry.dockerhub.id}" + email = "myself@company.com" + public_value = "myself" + secret_value = "mypass" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the registry credential. +* `description` - (Optional) A registry credential description. +* `registry_id` - (Required) The ID of the registry to create the credential for. +* `email` - (Required) The email of the account. +* `public_value` - (Required) The public value (user name) of the account. +* `secret_value` - (Required) The secret value (password) of the account. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the registry credential. +* `name` - (Required) The name of the registry credential. +* `description` - (Optional) The registry credential description. +* `registry_id` - (Required) The ID of the registry to create the credential for. +* `email` - (Required) The email of the account. +* `public_value` - (Required) The public value (user name) of the account. +* `secret_value` - (Required) The secret value (password) of the account. + +## Import + +Registry credentials can be imported using their Rancher API ID, e.g. + +``` +$ terraform import rancher_registry_credential.private_registry 1c605 +``` diff --git a/website/source/docs/providers/rancher/r/stack.html.markdown b/website/source/docs/providers/rancher/r/stack.html.markdown new file mode 100644 index 000000000000..ca6d746f1d9e --- /dev/null +++ b/website/source/docs/providers/rancher/r/stack.html.markdown @@ -0,0 +1,70 @@ +--- +layout: "rancher" +page_title: "Rancher: rancher_stack" +sidebar_current: "docs-rancher-resource-stack" +description: |- + Provides a Rancher Stack resource. This can be used to create and manage stacks on rancher. +--- + +# rancher\_stack + +Provides a Rancher Stack resource. This can be used to create and manage stacks on rancher. + +## Example Usage + +```hcl +# Create a new empty Rancher stack +resource "rancher_stack" "external-dns" { + name = "route53" + description = "Route53 stack" + environment_id = "${rancher_environment.default.id}" + catalog_id = "library:route53:7" + scope = "system" + environment { + AWS_ACCESS_KEY = "MYKEY" + AWS_SECRET_KEY = "MYSECRET" + AWS_REGION = "eu-central-1" + TTL = "60" + ROOT_DOMAIN = "example.com" + ROUTE53_ZONE_ID = "" + HEALTH_CHECK_INTERVAL = "15" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the stack. +* `description` - (Optional) A stack description. +* `environment_id` - (Required) The ID of the environment to create the stack for. +* `docker_compose` - (Optional) The `docker-compose.yml` content to apply for the stack. +* `rancher_compose` - (Optional) The `rancher-compose.yml` content to apply for the stack. +* `environment` - (Optional) The environment to apply to interpret the docker-compose and rancher-compose files. +* `catalog_id` - (Optional) The catalog ID to link this stack to. When provided, `docker_compose` and `rancher_compose` will be retrieved from the catalog unless they are overridden. +* `scope` - (Optional) The scope to attach the stack to. Must be one of **user** or **system**. Defaults to **user**. +* `start_on_create` - (Optional) Whether to start the stack automatically. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the stack. +* `name` - The name of the stack. +* `description` - The description of the stack. +* `environment_id` - (Required) The ID of the environment to create the stack for. +* `docker_compose` - (Optional) The `docker-compose.yml` content to apply for the stack. +* `rancher_compose` - (Optional) The `rancher-compose.yml` content to apply for the stack. +* `environment` - (Optional) The environment to apply to interpret the docker-compose and rancher-compose files. +* `catalog_id` - (Optional) The catalog ID to link this stack to. When provided, `docker_compose` and `rancher_compose` will be retrieved from the catalog unless they are overridden. +* `scope` - (Optional) The scope to attach the stack to. Must be one of **user** or **system**. Defaults to **user**. +* `start_on_create` - (Optional) Whether to start the stack automatically. + +## Import + +Stacks can be imported using their Rancher API ID, e.g. + +``` +$ terraform import rancher_stack.foo 1e149 +``` diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index b8c62a1673d5..d23435f06b5f 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -294,6 +294,10 @@ RabbitMQ + > + Rancher + + > Random diff --git a/website/source/layouts/rancher.erb b/website/source/layouts/rancher.erb new file mode 100644 index 000000000000..3dcd23373e5e --- /dev/null +++ b/website/source/layouts/rancher.erb @@ -0,0 +1,38 @@ +<% wrap_layout :inner do %> + <% content_for :sidebar do %> + + <% end %> + + <%= yield %> +<% end %>