diff --git a/docker/resource_docker_plugin.go b/docker/resource_docker_plugin.go
index cfb3712cb..e4207374c 100644
--- a/docker/resource_docker_plugin.go
+++ b/docker/resource_docker_plugin.go
@@ -14,11 +14,13 @@ func resourceDockerPlugin() *schema.Resource {
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
- "plugin_reference": {
- Type: schema.TypeString,
- Description: "Docker Plugin Reference",
- Required: true,
- ForceNew: true,
+ "name": {
+ Type: schema.TypeString,
+ Required: true,
+ ForceNew: true,
+ Description: "Docker Plugin name",
+ DiffSuppressFunc: diffSuppressFuncPluginName,
+ ValidateFunc: validateFuncPluginName,
},
"alias": {
Type: schema.TypeString,
@@ -68,6 +70,11 @@ func resourceDockerPlugin() *schema.Resource {
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
+ "plugin_reference": {
+ Type: schema.TypeString,
+ Description: "Docker Plugin Reference",
+ Computed: true,
+ },
"force_destroy": {
Type: schema.TypeBool,
diff --git a/docker/resource_docker_plugin_funcs.go b/docker/resource_docker_plugin_funcs.go
index 171c7a5f0..6b15efe9f 100644
--- a/docker/resource_docker_plugin_funcs.go
+++ b/docker/resource_docker_plugin_funcs.go
@@ -7,6 +7,7 @@ import (
"log"
"strings"
+ "github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
@@ -35,6 +36,33 @@ func complementTag(image string) string {
return image + ":latest"
}
+func normalizePluginName(name string) (string, error) {
+ ref, err := reference.ParseAnyReference(name)
+ if err != nil {
+ return "", fmt.Errorf("parse the plugin name: %w", err)
+ }
+ return complementTag(ref.String()), nil
+}
+
+func diffSuppressFuncPluginName(k, oldV, newV string, d *schema.ResourceData) bool {
+ o, err := normalizePluginName(oldV)
+ if err != nil {
+ return false
+ }
+ n, err := normalizePluginName(newV)
+ if err != nil {
+ return false
+ }
+ return o == n
+}
+
+func validateFuncPluginName(val interface{}, key string) (warns []string, errs []error) {
+ if _, err := normalizePluginName(val.(string)); err != nil {
+ return warns, append(errs, fmt.Errorf("%s is invalid: %w", key, err))
+ }
+ return
+}
+
func getDockerPluginGrantPermissions(src interface{}) func(types.PluginPrivileges) (bool, error) {
grantPermissionsSet := src.(*schema.Set)
grantPermissions := make(map[string]map[string]struct{}, grantPermissionsSet.Len())
@@ -69,11 +97,11 @@ func getDockerPluginGrantPermissions(src interface{}) func(types.PluginPrivilege
func resourceDockerPluginCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ProviderConfig).DockerClient
ctx := context.Background()
- pluginRef := d.Get("plugin_reference").(string)
+ pluginName := d.Get("name").(string)
alias := d.Get("alias").(string)
- log.Printf("[DEBUG] Install a Docker plugin " + pluginRef)
+ log.Printf("[DEBUG] Install a Docker plugin " + pluginName)
opts := types.PluginInstallOptions{
- RemoteRef: pluginRef,
+ RemoteRef: pluginName,
AcceptAllPermissions: d.Get("grant_all_permissions").(bool),
Disabled: !d.Get("enabled").(bool),
// TODO support other settings
@@ -84,10 +112,10 @@ func resourceDockerPluginCreate(d *schema.ResourceData, meta interface{}) error
}
body, err := client.PluginInstall(ctx, alias, opts)
if err != nil {
- return fmt.Errorf("install a Docker plugin "+pluginRef+": %w", err)
+ return fmt.Errorf("install a Docker plugin "+pluginName+": %w", err)
}
_, _ = ioutil.ReadAll(body)
- key := pluginRef
+ key := pluginName
if alias != "" {
key = alias
}
@@ -103,6 +131,7 @@ func setDockerPlugin(d *schema.ResourceData, plugin *types.Plugin) {
d.SetId(plugin.ID)
d.Set("plugin_reference", plugin.PluginReference)
d.Set("alias", plugin.Name)
+ d.Set("name", plugin.PluginReference)
d.Set("enabled", plugin.Enabled)
// TODO support other settings
// https://docs.docker.com/engine/reference/commandline/plugin_set/#extended-description
diff --git a/docker/resource_docker_plugin_test.go b/docker/resource_docker_plugin_test.go
index 6afb5c616..e57b96223 100644
--- a/docker/resource_docker_plugin_test.go
+++ b/docker/resource_docker_plugin_test.go
@@ -151,6 +151,7 @@ func TestAccDockerPlugin_basic(t *testing.T) {
ResourceName: resourceName,
Config: testAccDockerPluginMinimum,
Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr(resourceName, "name", "docker.io/tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "plugin_reference", "docker.io/tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "alias", "tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "enabled", "true"),
@@ -160,6 +161,7 @@ func TestAccDockerPlugin_basic(t *testing.T) {
ResourceName: resourceName,
Config: testAccDockerPluginAlias,
Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr(resourceName, "name", "docker.io/tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "plugin_reference", "docker.io/tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "alias", "sample:latest"),
resource.TestCheckResourceAttr(resourceName, "enabled", "true"),
@@ -169,6 +171,7 @@ func TestAccDockerPlugin_basic(t *testing.T) {
ResourceName: resourceName,
Config: testAccDockerPluginDisableWhenSet,
Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr(resourceName, "name", "docker.io/tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "plugin_reference", "docker.io/tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "alias", "sample:latest"),
resource.TestCheckResourceAttr(resourceName, "enabled", "true"),
@@ -181,6 +184,7 @@ func TestAccDockerPlugin_basic(t *testing.T) {
ResourceName: resourceName,
Config: testAccDockerPluginDisabled,
Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr(resourceName, "name", "docker.io/tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "plugin_reference", "docker.io/tiborvass/sample-volume-plugin:latest"),
resource.TestCheckResourceAttr(resourceName, "alias", "sample:latest"),
resource.TestCheckResourceAttr(resourceName, "enabled", "false"),
@@ -208,6 +212,7 @@ func TestAccDockerPlugin_grantAllPermissions(t *testing.T) {
ResourceName: resourceName,
Config: testAccDockerPluginGrantAllPermissions,
Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr(resourceName, "name", "docker.io/vieux/sshfs:latest"),
resource.TestCheckResourceAttr(resourceName, "plugin_reference", "docker.io/vieux/sshfs:latest"),
resource.TestCheckResourceAttr(resourceName, "alias", "vieux/sshfs:latest"),
resource.TestCheckResourceAttr(resourceName, "grant_all_permissions", "true"),
@@ -231,6 +236,7 @@ func TestAccDockerPlugin_grantPermissions(t *testing.T) {
ResourceName: resourceName,
Config: testAccDockerPluginGrantPermissions,
Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr(resourceName, "name", "docker.io/vieux/sshfs:latest"),
resource.TestCheckResourceAttr(resourceName, "plugin_reference", "docker.io/vieux/sshfs:latest"),
resource.TestCheckResourceAttr(resourceName, "alias", "vieux/sshfs:latest"),
),
@@ -245,24 +251,24 @@ func TestAccDockerPlugin_grantPermissions(t *testing.T) {
const testAccDockerPluginMinimum = `
resource "docker_plugin" "test" {
- plugin_reference = "docker.io/tiborvass/sample-volume-plugin:latest"
- force_destroy = true
+ name = "docker.io/tiborvass/sample-volume-plugin:latest"
+ force_destroy = true
}`
const testAccDockerPluginAlias = `
resource "docker_plugin" "test" {
- plugin_reference = "docker.io/tiborvass/sample-volume-plugin:latest"
+ name = "docker.io/tiborvass/sample-volume-plugin:latest"
alias = "sample:latest"
force_destroy = true
}`
const testAccDockerPluginDisableWhenSet = `
resource "docker_plugin" "test" {
- plugin_reference = "docker.io/tiborvass/sample-volume-plugin:latest"
- alias = "sample:latest"
- grant_all_permissions = true
- force_destroy = true
- enable_timeout = 60
+ name = "docker.io/tiborvass/sample-volume-plugin:latest"
+ alias = "sample:latest"
+ grant_all_permissions = true
+ force_destroy = true
+ enable_timeout = 60
env = [
"DEBUG=1"
]
@@ -270,13 +276,13 @@ resource "docker_plugin" "test" {
const testAccDockerPluginDisabled = `
resource "docker_plugin" "test" {
- plugin_reference = "docker.io/tiborvass/sample-volume-plugin:latest"
- alias = "sample:latest"
- enabled = false
- grant_all_permissions = true
- force_destroy = true
- force_disable = true
- enable_timeout = 60
+ name = "docker.io/tiborvass/sample-volume-plugin:latest"
+ alias = "sample:latest"
+ enabled = false
+ grant_all_permissions = true
+ force_destroy = true
+ force_disable = true
+ enable_timeout = 60
env = [
"DEBUG=1"
]
@@ -285,7 +291,7 @@ resource "docker_plugin" "test" {
// To install this plugin, it is required to grant required permissions.
const testAccDockerPluginGrantAllPermissions = `
resource "docker_plugin" "test" {
- plugin_reference = "docker.io/vieux/sshfs:latest"
+ name = "docker.io/vieux/sshfs:latest"
grant_all_permissions = true
force_destroy = true
}`
@@ -293,8 +299,8 @@ resource "docker_plugin" "test" {
// To install this plugin, it is required to grant required permissions.
const testAccDockerPluginGrantPermissions = `
resource "docker_plugin" "test" {
- plugin_reference = "docker.io/vieux/sshfs:latest"
- force_destroy = true
+ name = "vieux/sshfs"
+ force_destroy = true
grant_permissions {
name = "network"
value = [
diff --git a/go.mod b/go.mod
index ade4195fe..07b48e294 100644
--- a/go.mod
+++ b/go.mod
@@ -5,7 +5,7 @@ require (
github.com/Microsoft/hcsshim v0.8.9 // indirect
github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe // indirect
github.com/docker/cli v0.0.0-20200303215952-eb310fca4956 // v19.03.8
- github.com/docker/distribution v0.0.0-20180522175653-f0cc92778478 // indirect
+ github.com/docker/distribution v0.0.0-20180522175653-f0cc92778478
github.com/docker/docker v0.7.3-0.20190525203055-f25e0c6f3093
github.com/docker/docker-credential-helpers v0.6.3
github.com/docker/go-connections v0.4.0
diff --git a/website/docs/r/plugin.html.markdown b/website/docs/r/plugin.html.markdown
index 27cd250d6..8cd4489b0 100644
--- a/website/docs/r/plugin.html.markdown
+++ b/website/docs/r/plugin.html.markdown
@@ -14,14 +14,14 @@ Manages the lifecycle of a Docker plugin.
```hcl
resource "docker_plugin" "sample-volume-plugin" {
- plugin_reference = "docker.io/tiborvass/sample-volume-plugin:latest"
+ name = "docker.io/tiborvass/sample-volume-plugin:latest"
}
```
```hcl
resource "docker_plugin" "sample-volume-plugin" {
- plugin_reference = "docker.io/tiborvass/sample-volume-plugin:latest"
- alias = "sample-volume-plugin:latest"
+ name = "tiborvass/sample-volume-plugin"
+ alias = "sample-volume-plugin"
enabled = false
grant_all_permissions = true
force_destroy = true
@@ -37,7 +37,7 @@ resource "docker_plugin" "sample-volume-plugin" {
The following arguments are supported:
-* `plugin_reference` - (Required, string, Forces new resource) The plugin reference. The registry path and image tag should not be omitted. See [plugin_references, alias](#plugin-references-alias-1) below for details.
+* `name` - (Required, string, Forces new resource) The plugin name. If the tag is omitted, `:latest` is complemented to the attribute value.
* `alias` - (Optional, string, Forces new resource) The alias of the Docker plugin. If the tag is omitted, `:latest` is complemented to the attribute value.
* `enabled` - (Optional, boolean) If true, the plugin is enabled. The default value is `true`.
* `grant_all_permissions` - (Optional, boolean) If true, grant all permissions necessary to run the plugin. This attribute conflicts with `grant_permissions`.
@@ -47,47 +47,6 @@ The following arguments are supported:
* `enable_timeout` - (Optional, int) HTTP client timeout to enable the plugin.
* `force_disable` - (Optional, boolean) If true, then the plugin is disabled forcibly when the plugin is disabled.
-
-## plugin_reference
-
-`plugin_reference` must be full path. Otherwise, after `terraform apply` is run, there would be diffs of them.
-
-For example,
-
-```hcl
-resource "docker_plugin" "sample-volume-plugin" {
- plugin_reference = "tiborvass/sample-volume-plugin" # must be "docker.io/tiborvass/sample-volume-plugin:latest"
- alias = "sample"
-}
-```
-
-```sh
-$ terraform apply # a plugin is installed
-
-Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
-
-$ terraform plan
-
-An execution plan has been generated and is shown below.
-Resource actions are indicated with the following symbols:
--/+ destroy and then create replacement
-
-Terraform will perform the following actions:
-
- # docker_plugin.sample-volume-plugin must be replaced
--/+ resource "docker_plugin" "sample-volume-plugin" {
- ~ alias = "sample:latest" -> "sample:latest"
- - enabled = false -> null
- ~ env = [
- - "DEBUG=0",
- ] -> (known after apply)
- ~ id = "27784976e1471c1e473a901a0a02055ddc8bc1c9dec9c44d81a49d516c0c28f9" -> (known after apply)
- ~ plugin_reference = "docker.io/tiborvass/sample-volume-plugin:latest" -> "tiborvass/sample-volume-plugin" # forces replacement
- }
-
-Plan: 1 to add, 0 to change, 1 to destroy.
-```
-
## grant_permissions
@@ -101,7 +60,7 @@ Example:
```hcl
resource "docker_plugin" "sshfs" {
- plugin_reference = "docker.io/vieux/sshfs:latest"
+ name = "docker.io/vieux/sshfs:latest"
grant_permissions {
name = "network"
value = [
@@ -132,6 +91,8 @@ resource "docker_plugin" "sshfs" {
## Attributes Reference
+* `plugin_reference` - (string) The plugin reference.
+
## Import
Docker plugins can be imported using the long id, e.g. for a plugin `tiborvass/sample-volume-plugin:latest`: