diff --git a/backend/remote-state/swift/backend.go b/backend/remote-state/swift/backend.go index 567dc0644..3a22438f5 100644 --- a/backend/remote-state/swift/backend.go +++ b/backend/remote-state/swift/backend.go @@ -9,29 +9,35 @@ import ( "time" "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/openstack" + "github.com/gophercloud/utils/terraform/auth" "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/helper/schema" - tf_openstack "github.com/terraform-providers/terraform-provider-openstack/openstack" + "github.com/hashicorp/terraform/version" ) +// Use openstackbase.Config as the base/foundation of this provider's +// Config struct. +type Config struct { + auth.Config +} + // New creates a new backend for Swift remote state. func New() backend.Backend { s := &schema.Backend{ Schema: map[string]*schema.Schema{ "auth_url": { Type: schema.TypeString, - Required: true, + Optional: true, DefaultFunc: schema.EnvDefaultFunc("OS_AUTH_URL", ""), Description: descriptions["auth_url"], }, - "user_id": { + "region_name": { Type: schema.TypeString, Optional: true, - DefaultFunc: schema.EnvDefaultFunc("OS_USER_ID", ""), - Description: descriptions["user_name"], + Description: descriptions["region_name"], + DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""), }, "user_name": { @@ -41,6 +47,13 @@ func New() backend.Backend { Description: descriptions["user_name"], }, + "user_id": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("OS_USER_ID", ""), + Description: descriptions["user_name"], + }, + "application_credential_id": { Type: schema.TypeString, Optional: true, @@ -149,20 +162,6 @@ func New() backend.Backend { Description: descriptions["default_domain"], }, - "cloud": { - Type: schema.TypeString, - Optional: true, - DefaultFunc: schema.EnvDefaultFunc("OS_CLOUD", ""), - Description: descriptions["cloud"], - }, - - "region_name": { - Type: schema.TypeString, - Required: true, - DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""), - Description: descriptions["region_name"], - }, - "insecure": { Type: schema.TypeBool, Optional: true, @@ -197,6 +196,41 @@ func New() backend.Backend { Description: descriptions["key"], }, + "swauth": { + Type: schema.TypeBool, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("OS_SWAUTH", false), + Description: descriptions["swauth"], + }, + + "allow_reauth": { + Type: schema.TypeBool, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("OS_ALLOW_REAUTH", false), + Description: descriptions["allow_reauth"], + }, + + "cloud": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("OS_CLOUD", ""), + Description: descriptions["cloud"], + }, + + "max_retries": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + Description: descriptions["max_retries"], + }, + + "disable_no_cache_header": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: descriptions["disable_no_cache_header"], + }, + "path": { Type: schema.TypeString, Optional: true, @@ -258,6 +292,8 @@ func init() { descriptions = map[string]string{ "auth_url": "The Identity authentication URL.", + "region_name": "The name of the Region to use.", + "user_name": "Username to login with.", "user_id": "User ID to login with.", @@ -292,10 +328,6 @@ func init() { "default_domain": "The name of the Domain ID to scope to if no other domain is specified. Defaults to `default` (Identity v3).", - "cloud": "An entry in a `clouds.yaml` file to use.", - - "region_name": "The name of the Region to use.", - "insecure": "Trust self-signed certificates.", "cacert_file": "A Custom CA certificate.", @@ -306,6 +338,19 @@ func init() { "key": "A client private key to authenticate with.", + "swauth": "Use Swift's authentication system instead of Keystone.", + + "allow_reauth": "If set to `true`, OpenStack authorization will be perfomed\n" + + "automatically, if the initial auth token get expired. This is useful,\n" + + "when the token TTL is low or the overall Terraform provider execution\n" + + "time expected to be greater than the initial token TTL.", + + "cloud": "An entry in a `clouds.yaml` file to use.", + + "max_retries": "How many times HTTP connection should be retried until giving up.", + + "disable_no_cache_header": "If set to `true`, the HTTP `Cache-Control: no-cache` header will not be added by default to all API requests.", + "path": "Swift container path to use.", "container": "Swift container to create", @@ -340,29 +385,37 @@ func (b *Backend) configure(ctx context.Context) error { // Grab the resource data data := schema.FromContextBackendConfig(ctx) - config := &tf_openstack.Config{ - CACertFile: data.Get("cacert_file").(string), - ClientCertFile: data.Get("cert").(string), - ClientKeyFile: data.Get("key").(string), - Cloud: data.Get("cloud").(string), - DefaultDomain: data.Get("default_domain").(string), - DomainID: data.Get("domain_id").(string), - DomainName: data.Get("domain_name").(string), - EndpointType: data.Get("endpoint_type").(string), - IdentityEndpoint: data.Get("auth_url").(string), - Password: data.Get("password").(string), - ProjectDomainID: data.Get("project_domain_id").(string), - ProjectDomainName: data.Get("project_domain_name").(string), - Token: data.Get("token").(string), - TenantID: data.Get("tenant_id").(string), - TenantName: data.Get("tenant_name").(string), - UserDomainID: data.Get("user_domain_id").(string), - UserDomainName: data.Get("user_domain_name").(string), - Username: data.Get("user_name").(string), - UserID: data.Get("user_id").(string), - ApplicationCredentialID: data.Get("application_credential_id").(string), - ApplicationCredentialName: data.Get("application_credential_name").(string), - ApplicationCredentialSecret: data.Get("application_credential_secret").(string), + config := &Config{ + auth.Config{ + CACertFile: data.Get("cacert_file").(string), + ClientCertFile: data.Get("cert").(string), + ClientKeyFile: data.Get("key").(string), + Cloud: data.Get("cloud").(string), + DefaultDomain: data.Get("default_domain").(string), + DomainID: data.Get("domain_id").(string), + DomainName: data.Get("domain_name").(string), + EndpointType: data.Get("endpoint_type").(string), + IdentityEndpoint: data.Get("auth_url").(string), + Password: data.Get("password").(string), + ProjectDomainID: data.Get("project_domain_id").(string), + ProjectDomainName: data.Get("project_domain_name").(string), + Region: data.Get("region_name").(string), + Swauth: data.Get("swauth").(bool), + Token: data.Get("token").(string), + TenantID: data.Get("tenant_id").(string), + TenantName: data.Get("tenant_name").(string), + UserDomainID: data.Get("user_domain_id").(string), + UserDomainName: data.Get("user_domain_name").(string), + Username: data.Get("user_name").(string), + UserID: data.Get("user_id").(string), + ApplicationCredentialID: data.Get("application_credential_id").(string), + ApplicationCredentialName: data.Get("application_credential_name").(string), + ApplicationCredentialSecret: data.Get("application_credential_secret").(string), + AllowReauth: data.Get("allow_reauth").(bool), + MaxRetries: data.Get("max_retries").(int), + DisableNoCacheHeader: data.Get("disable_no_cache_header").(bool), + TerraformVersion: version.Version, + }, } if v, ok := data.GetOkExists("insecure"); ok { @@ -423,14 +476,10 @@ func (b *Backend) configure(ctx context.Context) error { b.expireSecs = int(expireDur.Seconds()) } - objClient, err := openstack.NewObjectStorageV1(config.OsClient, gophercloud.EndpointOpts{ - Region: data.Get("region_name").(string), - }) - if err != nil { + var err error + if b.client, err = config.ObjectStorageV1Client(config.Region); err != nil { return err } - b.client = objClient - return nil } diff --git a/website/docs/backends/types/swift.html.md b/website/docs/backends/types/swift.html.md index d201ef945..6230f3b49 100644 --- a/website/docs/backends/types/swift.html.md +++ b/website/docs/backends/types/swift.html.md @@ -45,7 +45,7 @@ data "terraform_remote_state" "foo" { The following configuration options are supported: - * `auth_url` - (Required) The Identity authentication URL. If omitted, the +* `auth_url` - (Optional) The Identity authentication URL. If omitted, the `OS_AUTH_URL` environment variable is used. * `cloud` - (Optional; required if `auth_url` is not specified) An entry in a @@ -54,59 +54,53 @@ The following configuration options are supported: for more information about `clouds.yaml` files. If omitted, the `OS_CLOUD` environment variable is used. - * `container` - (Required) The name of the container to create for storing - the Terraform state file. - - * `state_name` - (Optional) The name of the state file in the container. - Defaults to `tfstate.tf`. - - * `path` - (Optional) DEPRECATED: Use `container` instead. - The name of the container to create in order to store the state file. - - * `user_name` - (Optional) The Username to login with. If omitted, the - `OS_USERNAME` environment variable is used. - - * `user_id` - (Optional) The User ID to login with. If omitted, the - `OS_USER_ID` environment variable is used. - - * `password` - (Optional) The Password to login with. If omitted, the - `OS_PASSWORD` environment variable is used. - - * `application_credential_id` - (Optional) (Identity v3 only) The ID of an - application credential to authenticate with. An - `application_credential_secret` has to bet set along with this parameter. - - * `application_credential_name` - (Optional) (Identity v3 only) The name of an - application credential to authenticate with. Conflicts with the - `application_credential_name`, requires `user_id`, or `user_name` and - `domain_name` (or `domain_id`) to be set. - - * `application_credential_secret` - (Optional) (Identity v3 only) The secret of an - application credential to authenticate with. Required by - `application_credential_id` or `application_credential_name`. - - * `token` - (Optional) Access token to login with instead of user and password. - If omitted, the `OS_AUTH_TOKEN` variable is used. - - * `region_name` (Required) - The region in which to store `terraform.tfstate`. If +* `region_name` - (Optional) - The region in which to store `terraform.tfstate`. If omitted, the `OS_REGION_NAME` environment variable is used. - * `tenant_id` (Optional) The ID of the Tenant (Identity v2) or Project - (Identity v3) to login with. If omitted, the `OS_TENANT_ID` or - `OS_PROJECT_ID` environment variables are used. +* `container` - (Required) The name of the container to create for storing + the Terraform state file. - * `tenant_name` - (Optional) The Name of the Tenant (Identity v2) or Project - (Identity v3) to login with. If omitted, the `OS_TENANT_NAME` or - `OS_PROJECT_NAME` environment variable are used. +* `state_name` - (Optional) The name of the state file in the container. + Defaults to `tfstate.tf`. - * `domain_id` - (Optional) The ID of the Domain to scope to (Identity v3). If - omitted, the following environment variables are checked (in this order): - `OS_USER_DOMAIN_ID`, `OS_PROJECT_DOMAIN_ID`, `OS_DOMAIN_ID`. +* `path` - (Optional) DEPRECATED: Use `container` instead. + The name of the container to create in order to store the state file. - * `domain_name` - (Optional) The Name of the Domain to scope to (Identity v3). - If omitted, the following environment variables are checked (in this order): - `OS_USER_DOMAIN_NAME`, `OS_PROJECT_DOMAIN_NAME`, `OS_DOMAIN_NAME`, - `DEFAULT_DOMAIN`. +* `user_name` - (Optional) The Username to login with. If omitted, the + `OS_USERNAME` environment variable is used. + +* `user_id` - (Optional) The User ID to login with. If omitted, the + `OS_USER_ID` environment variable is used. + +* `application_credential_id` - (Optional) (Identity v3 only) The ID of an + application credential to authenticate with. An + `application_credential_secret` has to bet set along with this parameter. + +* `application_credential_name` - (Optional) (Identity v3 only) The name of an + application credential to authenticate with. Requires `user_id`, or + `user_name` and `user_domain_name` (or `user_domain_id`) to be set. + +* `application_credential_secret` - (Optional) (Identity v3 only) The secret of an + application credential to authenticate with. Required by + `application_credential_id` or `application_credential_name`. + +* `tenant_id` - (Optional) The ID of the Tenant (Identity v2) or Project + (Identity v3) to login with. If omitted, the `OS_TENANT_ID` or + `OS_PROJECT_ID` environment variables are used. + +* `tenant_name` - (Optional) The Name of the Tenant (Identity v2) or Project + (Identity v3) to login with. If omitted, the `OS_TENANT_NAME` or + `OS_PROJECT_NAME` environment variable are used. + +* `password` - (Optional) The Password to login with. If omitted, the + `OS_PASSWORD` environment variable is used. + +* `token` - (Optional; Required if not using `user_name` and `password`) + A token is an expiring, temporary means of access issued via the Keystone + service. By specifying a token, you do not have to specify a username/password + combination, since the token was already created by a username/password out of + band of Terraform. If omitted, the `OS_TOKEN` or `OS_AUTH_TOKEN` environment + variables are used. * `user_domain_name` - (Optional) The domain name where the user is located. If omitted, the `OS_USER_DOMAIN_NAME` environment variable is checked. @@ -121,30 +115,60 @@ The following configuration options are supported: * `project_domain_id` - (Optional) The domain ID where the project is located If omitted, the `OS_PROJECT_DOMAIN_ID` environment variable is checked. +* `domain_id` - (Optional) The ID of the Domain to scope to (Identity v3). If + omitted, the following environment variables are checked (in this order): + `OS_USER_DOMAIN_ID`, `OS_PROJECT_DOMAIN_ID`, `OS_DOMAIN_ID`. + +* `domain_name` - (Optional) The Name of the Domain to scope to (Identity v3). + If omitted, the following environment variables are checked (in this order): + `OS_USER_DOMAIN_NAME`, `OS_PROJECT_DOMAIN_NAME`, `OS_DOMAIN_NAME`, + `DEFAULT_DOMAIN`. + * `default_domain` - (Optional) The ID of the Domain to scope to if no other domain is specified (Identity v3). If omitted, the environment variable `OS_DEFAULT_DOMAIN` is checked or a default value of "default" will be used. - * `insecure` - (Optional) Trust self-signed SSL certificates. If omitted, the - `OS_INSECURE` environment variable is used. +* `insecure` - (Optional) Trust self-signed SSL certificates. If omitted, the + `OS_INSECURE` environment variable is used. - * `cacert_file` - (Optional) Specify a custom CA certificate when communicating - over SSL. If omitted, the `OS_CACERT` environment variable is used. +* `cacert_file` - (Optional) Specify a custom CA certificate when communicating + over SSL. You can specify either a path to the file or the contents of the + certificate. If omitted, the `OS_CACERT` environment variable is used. - * `cert` - (Optional) Specify client certificate file for SSL client authentication. +* `cert` - (Optional) Specify client certificate file for SSL client authentication. If omitted the `OS_CERT` environment variable is used. - * `key` - (Optional) Specify client private key file for SSL client authentication. +* `key` - (Optional) Specify client private key file for SSL client authentication. If omitted the `OS_KEY` environment variable is used. - * `archive_container` - (Optional) The container to create to store archived copies - of the Terraform state file. If specified, Swift [object versioning](https://docs.openstack.org/developer/swift/latest/overview_object_versioning.html) is enabled on the container created at `container`. +* `endpoint_type` - (Optional) Specify which type of endpoint to use from the + service catalog. It can be set using the OS_ENDPOINT_TYPE environment + variable. If not set, public endpoints is used. - * `archive_path` - (Optional) DEPRECATED: Use `archive_container` instead. - The path to store archived copied of `terraform.tfstate`. If specified, - Swift [object versioning](https://docs.openstack.org/developer/swift/latest/overview_object_versioning.html) is enabled on the container created at `path`. +* `swauth` - (Optional) Set to `true` to authenticate against Swauth, a + Swift-native authentication system. If omitted, the `OS_SWAUTH` environment + variable is used. You must also set `username` to the Swauth/Swift username + such as `username:project`. Set the `password` to the Swauth/Swift key. + Finally, set `auth_url` as the location of the Swift service. - * `expire_after` - (Optional) How long should the `terraform.tfstate` created at `container` - be retained for? If specified, Swift [expiring object support](https://docs.openstack.org/developer/swift/latest/overview_expiring_objects.html) is enabled on the state. Supported durations: `m` - Minutes, `h` - Hours, `d` - Days. - ~> **NOTE:** Since Terraform is inherently stateful - we'd strongly recommend against auto-expiring Statefiles. +* `disable_no_cache_header` - (Optional) If set to `true`, the HTTP + `Cache-Control: no-cache` header will not be added by default to all API requests. + If omitted this header is added to all API requests to force HTTP caches (if any) + to go upstream instead of serving cached responses. + +* `allow_reauth` - (Optional) If set to `true`, OpenStack authorization will be + perfomed automatically, if the initial auth token get expired. This is useful, + when the token TTL is low or the overall Terraform provider execution time + expected to be greater than the initial token TTL. + +* `archive_container` - (Optional) The container to create to store archived copies + of the Terraform state file. If specified, Swift [object versioning](https://docs.openstack.org/developer/swift/latest/overview_object_versioning.html) is enabled on the container created at `container`. + +* `archive_path` - (Optional) DEPRECATED: Use `archive_container` instead. + The path to store archived copied of `terraform.tfstate`. If specified, + Swift [object versioning](https://docs.openstack.org/developer/swift/latest/overview_object_versioning.html) is enabled on the container created at `path`. + +* `expire_after` - (Optional) How long should the `terraform.tfstate` created at `container` + be retained for? If specified, Swift [expiring object support](https://docs.openstack.org/developer/swift/latest/overview_expiring_objects.html) is enabled on the state. Supported durations: `m` - Minutes, `h` - Hours, `d` - Days. + ~> **NOTE:** Since Terraform is inherently stateful - we'd strongly recommend against auto-expiring Statefiles.