mirror of
https://github.com/kreuzwerker/terraform-provider-docker.git
synced 2026-02-03 12:19:29 -05:00
feat: Implement auth_config for docker_registry_image (#701)
* feat: Implement auth_config for docker_registry_image * fix: Formatting
This commit is contained in:
parent
1b354111b4
commit
98ccee6b68
5 changed files with 115 additions and 8 deletions
|
|
@ -37,6 +37,7 @@ resource "docker_image" "image" {
|
|||
|
||||
### Optional
|
||||
|
||||
- `auth_config` (Block List, Max: 1) Authentication configuration for the Docker registry. It is only used for this resource. (see [below for nested schema](#nestedblock--auth_config))
|
||||
- `insecure_skip_verify` (Boolean) If `true`, the verification of TLS certificates of the server/registry is disabled. Defaults to `false`
|
||||
- `keep_remotely` (Boolean) If true, then the Docker image won't be deleted on destroy operation. If this is false, it will delete the image from the docker registry on destroy operation. Defaults to `false`
|
||||
- `triggers` (Map of String) A map of arbitrary strings that, when changed, will force the `docker_registry_image` resource to be replaced. This can be used to repush a local image
|
||||
|
|
@ -44,4 +45,13 @@ resource "docker_image" "image" {
|
|||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `sha256_digest` (String) The sha256 digest of the image.
|
||||
- `sha256_digest` (String) The sha256 digest of the image.
|
||||
|
||||
<a id="nestedblock--auth_config"></a>
|
||||
### Nested Schema for `auth_config`
|
||||
|
||||
Required:
|
||||
|
||||
- `address` (String) The address of the Docker registry.
|
||||
- `password` (String, Sensitive) The password for the Docker registry.
|
||||
- `username` (String) The username for the Docker registry.
|
||||
|
|
@ -47,6 +47,33 @@ func resourceDockerRegistryImage() *schema.Resource {
|
|||
Description: "The sha256 digest of the image.",
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"auth_config": {
|
||||
Type: schema.TypeList,
|
||||
Description: "Authentication configuration for the Docker registry. It is only used for this resource.",
|
||||
Optional: true,
|
||||
MaxItems: 1,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"address": {
|
||||
Type: schema.TypeString,
|
||||
Description: "The address of the Docker registry.",
|
||||
Required: true,
|
||||
},
|
||||
"username": {
|
||||
Type: schema.TypeString,
|
||||
Description: "The username for the Docker registry.",
|
||||
Required: true,
|
||||
},
|
||||
"password": {
|
||||
Type: schema.TypeString,
|
||||
Description: "The password for the Docker registry.",
|
||||
Required: true,
|
||||
Sensitive: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,16 @@ import (
|
|||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func buildAuthConfigFromResource(v interface{}) registry.AuthConfig {
|
||||
auth := v.([]interface{})[0].(map[string]interface{})
|
||||
return registry.AuthConfig{
|
||||
ServerAddress: normalizeRegistryAddress(auth["address"].(string)),
|
||||
Username: auth["username"].(string),
|
||||
Password: auth["password"].(string),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func resourceDockerRegistryImageCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
client := meta.(*ProviderConfig).DockerClient
|
||||
providerConfig := meta.(*ProviderConfig)
|
||||
|
|
@ -30,10 +40,19 @@ func resourceDockerRegistryImageCreate(ctx context.Context, d *schema.ResourceDa
|
|||
|
||||
pushOpts := createPushImageOptions(name)
|
||||
|
||||
authConfig, err := getAuthConfigForRegistry(pushOpts.Registry, providerConfig)
|
||||
if err != nil {
|
||||
return diag.Errorf("resourceDockerRegistryImageCreate: Unable to get authConfig for registry: %s", err)
|
||||
var authConfig registry.AuthConfig
|
||||
if v, ok := d.GetOk("auth_config"); ok {
|
||||
log.Printf("[INFO] Using auth config from resource: %s", v)
|
||||
authConfig = buildAuthConfigFromResource(v)
|
||||
} else {
|
||||
log.Printf("[INFO] Using auth config from provider: %s", v)
|
||||
var err error
|
||||
authConfig, err = getAuthConfigForRegistry(pushOpts.Registry, providerConfig)
|
||||
if err != nil {
|
||||
return diag.Errorf("resourceDockerRegistryImageCreate: Unable to get authConfig for registry: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := pushDockerRegistryImage(ctx, client, pushOpts, authConfig.Username, authConfig.Password); err != nil {
|
||||
return diag.Errorf("Error pushing docker image: %s", err)
|
||||
}
|
||||
|
|
@ -41,7 +60,7 @@ func resourceDockerRegistryImageCreate(ctx context.Context, d *schema.ResourceDa
|
|||
insecureSkipVerify := d.Get("insecure_skip_verify").(bool)
|
||||
digest, err := getImageDigestWithFallback(pushOpts, authConfig.ServerAddress, authConfig.Username, authConfig.Password, insecureSkipVerify)
|
||||
if err != nil {
|
||||
return diag.Errorf("Unable to create image, image not found: %s", err)
|
||||
return diag.Errorf("Got error getting registry image digest inside resourceDockerRegistryImageCreate: %s", err)
|
||||
}
|
||||
d.SetId(digest)
|
||||
d.Set("sha256_digest", digest)
|
||||
|
|
@ -52,9 +71,16 @@ func resourceDockerRegistryImageRead(ctx context.Context, d *schema.ResourceData
|
|||
providerConfig := meta.(*ProviderConfig)
|
||||
name := d.Get("name").(string)
|
||||
pushOpts := createPushImageOptions(name)
|
||||
authConfig, err := getAuthConfigForRegistry(pushOpts.Registry, providerConfig)
|
||||
if err != nil {
|
||||
return diag.Errorf("resourceDockerRegistryImageRead: Unable to get authConfig for registry: %s", err)
|
||||
|
||||
var authConfig registry.AuthConfig
|
||||
if v, ok := d.GetOk("auth_config"); ok {
|
||||
authConfig = buildAuthConfigFromResource(v)
|
||||
} else {
|
||||
var err error
|
||||
authConfig, err = getAuthConfigForRegistry(pushOpts.Registry, providerConfig)
|
||||
if err != nil {
|
||||
return diag.Errorf("resourceDockerRegistryImageRead: Unable to get authConfig for registry: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
insecureSkipVerify := d.Get("insecure_skip_verify").(bool)
|
||||
|
|
|
|||
|
|
@ -66,6 +66,26 @@ func TestAccDockerRegistryImageResource_pushMissingImage(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccDockerRegistryImageResource_withAuthConfig(t *testing.T) {
|
||||
pushOptions := createPushImageOptions("127.0.0.1:15000/tftest-dockerregistryimage:1.0")
|
||||
wd, _ := os.Getwd()
|
||||
context := strings.ReplaceAll(filepath.Join(wd, "..", "..", "scripts", "testing", "docker_registry_image_context"), "\\", "\\\\")
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
ProviderFactories: providerFactories,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: fmt.Sprintf(loadTestConfiguration(t, RESOURCE, "docker_registry_image", "testBuildDockerRegistryImageWithAuthConfig"), pushOptions.Name, context, pushOptions.Registry, "testuser", "testpwd"),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttrSet("docker_registry_image.foo", "sha256_digest"),
|
||||
),
|
||||
},
|
||||
},
|
||||
CheckDestroy: testDockerRegistryImageInRegistry("testuser", "testpwd", pushOptions, true),
|
||||
})
|
||||
}
|
||||
|
||||
func testDockerRegistryImageNotInRegistry(pushOpts internalPushImageOptions) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
providerConfig := testAccProvider.Meta().(*ProviderConfig)
|
||||
|
|
|
|||
24
testdata/resources/docker_registry_image/testBuildDockerRegistryImageWithAuthConfig.tf
vendored
Normal file
24
testdata/resources/docker_registry_image/testBuildDockerRegistryImageWithAuthConfig.tf
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
provider "docker" {
|
||||
alias = "private"
|
||||
}
|
||||
|
||||
resource "docker_image" "foo_image" {
|
||||
provider = docker.private
|
||||
name = "%s"
|
||||
build {
|
||||
context = "%s"
|
||||
}
|
||||
}
|
||||
|
||||
resource "docker_registry_image" "foo" {
|
||||
provider = docker.private
|
||||
name = docker_image.foo_image.name
|
||||
insecure_skip_verify = true
|
||||
keep_remotely = true
|
||||
|
||||
auth_config {
|
||||
address = "%s"
|
||||
username = "%s"
|
||||
password = "%s"
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue