From 2901e513a84f78d66403b07c754c3b370bdf85d5 Mon Sep 17 00:00:00 2001 From: Nick Santos Date: Fri, 20 Dec 2024 10:12:30 -0500 Subject: [PATCH] provider: add password back fixes https://github.com/docker/terraform-provider-docker/issues/77 Signed-off-by: Nick Santos --- docs/index.md | 87 ++++++++++++++++++++++++++++++++--- internal/provider/provider.go | 67 +++++++++++++++++++++++++-- 2 files changed, 142 insertions(+), 12 deletions(-) diff --git a/docs/index.md b/docs/index.md index 5e0821a..fb3e8f5 100644 --- a/docs/index.md +++ b/docs/index.md @@ -28,14 +28,34 @@ description: |- Authentication We have multiple ways to set your Docker credentials. - Setting credentials - Use docker login to log in to aregistry https://docs.docker.com/reference/cli/docker/login/. The docker CLI + Setting credentials with docker login + To login in an interactive command-line: + + docker login + + To login in a non-interactive script: + + cat ~/my_password.txt | docker login --username my-username --password-stdin + + The docker CLI will store your credentials securely in your credential store, such as the operating system native keychain. The Docker Terraform provider will use these credentials automatically. + Setting credentials in CI + The Docker Terraform provider will work with your CI provider's + native Docker login action. For example, in GitHub Actions https://github.com/marketplace/actions/docker-login: - cat ~/my_password.txt | docker login --username my-username --password-stdin + jobs: + login: + runs-on: ubuntu-latest + steps: + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ vars.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + Setting credentials with environment variables If you'd like to use a different account for running the provider, you can set credentials in the environment: @@ -43,6 +63,16 @@ description: |- export DOCKER_PASSWORD=my-secret-token terraform plan ... + Setting credentials in Terraform (NOT RECOMMENDED) + [!WARNING]Hard-coding secrets in Terraform is risky. You risk leaking the secretsif they're committed to version control. + Only pass in a password in Terraform if you're pulling the secret from a secure + location, or if you're doing local testing. + + provider "docker" { + username = "my-username" + password = "my-password" + } + Credential types You can create a personal access token (PAT) to use as an alternative to your password for Docker CLI authentication. @@ -90,18 +120,44 @@ resource "docker_repository" "example" { We have multiple ways to set your Docker credentials. -### Setting credentials +### Setting credentials with `docker login` + +To login in an interactive command-line: + +``` +docker login +``` + +To login in a non-interactive script: + +``` +cat ~/my_password.txt | docker login --username my-username --password-stdin +``` -Use `docker login` to [log in to a -registry](https://docs.docker.com/reference/cli/docker/login/). The `docker` CLI +The `docker` CLI will store your credentials securely in your credential store, such as the operating system native keychain. The Docker Terraform provider will use these credentials automatically. +### Setting credentials in CI + +The Docker Terraform provider will work with your CI provider's +native Docker login action. For example, in [GitHub Actions](https://github.com/marketplace/actions/docker-login): + ``` -cat ~/my_password.txt | docker login --username my-username --password-stdin +jobs: + login: + runs-on: ubuntu-latest + steps: + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ vars.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} ``` +### Setting credentials with environment variables + If you'd like to use a different account for running the provider, you can set credentials in the environment: @@ -111,6 +167,22 @@ export DOCKER_PASSWORD=my-secret-token terraform plan ... ``` +### Setting credentials in Terraform (NOT RECOMMENDED) + +> [!WARNING] +> Hard-coding secrets in Terraform is risky. You risk leaking the secrets +> if they're committed to version control. + +Only pass in a password in Terraform if you're pulling the secret from a secure +location, or if you're doing local testing. + +```hcl +provider "docker" { + username = "my-username" + password = "my-password" +} +``` + ### Credential types You can create a personal access token (PAT) to use as an alternative to your @@ -134,4 +206,5 @@ this provider to manage organizations and teams, you will need to authenticate ### Optional - `host` (String) Docker Hub API Host. Default is `hub.docker.com`. +- `password` (String, Sensitive) Password for authentication - `username` (String) Username for authentication diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 62c6892..a19ea9d 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -60,6 +60,7 @@ type DockerProvider struct { // DockerProviderModel describes the provider data model. type DockerProviderModel struct { Username types.String `tfsdk:"username"` + Password types.String `tfsdk:"password"` Host types.String `tfsdk:"host"` } @@ -105,18 +106,44 @@ resource "docker_repository" "example" { We have multiple ways to set your Docker credentials. -### Setting credentials +### Setting credentials with ` + "`docker login`" + ` -Use ` + "`docker login`" + ` to [log in to a -registry](https://docs.docker.com/reference/cli/docker/login/). The ` + "`docker`" + ` CLI +To login in an interactive command-line: + +` + "```" + ` +docker login +` + "```" + ` + +To login in a non-interactive script: + +` + "```" + ` +cat ~/my_password.txt | docker login --username my-username --password-stdin +` + "```" + ` + +The ` + "`docker`" + ` CLI will store your credentials securely in your credential store, such as the operating system native keychain. The Docker Terraform provider will use these credentials automatically. +### Setting credentials in CI + +The Docker Terraform provider will work with your CI provider's +native Docker login action. For example, in [GitHub Actions](https://github.com/marketplace/actions/docker-login): + ` + "```" + ` -cat ~/my_password.txt | docker login --username my-username --password-stdin +jobs: + login: + runs-on: ubuntu-latest + steps: + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ vars.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} ` + "```" + ` +### Setting credentials with environment variables + If you'd like to use a different account for running the provider, you can set credentials in the environment: @@ -126,6 +153,22 @@ export DOCKER_PASSWORD=my-secret-token terraform plan ... ` + "```" + ` +### Setting credentials in Terraform (NOT RECOMMENDED) + +> [!WARNING] +> Hard-coding secrets in Terraform is risky. You risk leaking the secrets +> if they're committed to version control. + +Only pass in a password in Terraform if you're pulling the secret from a secure +location, or if you're doing local testing. + +` + "```" + `hcl +provider "docker" { + username = "my-username" + password = "my-password" +} +` + "```" + ` + ### Credential types You can create a personal access token (PAT) to use as an alternative to your @@ -153,6 +196,11 @@ this provider to manage organizations and teams, you will need to authenticate MarkdownDescription: "Username for authentication", Optional: true, }, + "password": schema.StringAttribute{ + MarkdownDescription: "Password for authentication", + Optional: true, + Sensitive: true, + }, }, } } @@ -174,7 +222,6 @@ func (p *DockerProvider) Configure(ctx context.Context, req provider.ConfigureRe "Either target apply the source of the value first, set the value statically in the configuration, or use the DOCKER_HUB_HOST environment variable.", ) } - if data.Username.IsUnknown() { resp.Diagnostics.AddAttributeError( path.Root("username"), @@ -182,6 +229,13 @@ func (p *DockerProvider) Configure(ctx context.Context, req provider.ConfigureRe "The provider cannot create the Docker Hub API client as there is an unknown configuration value for the Docker Hub API username.", ) } + if data.Password.IsUnknown() { + resp.Diagnostics.AddAttributeError( + path.Root("password"), + "Unknown Docker Hub API Password", + "The provider cannot create the Docker Hub API client as there is an unknown configuration value for the Docker Hub API password.", + ) + } if resp.Diagnostics.HasError() { return @@ -203,6 +257,9 @@ func (p *DockerProvider) Configure(ctx context.Context, req provider.ConfigureRe } password := os.Getenv("DOCKER_PASSWORD") + if !data.Password.IsNull() { + password = data.Password.ValueString() + } // If DOCKER_USERNAME and DOCKER_PASSWORD are not set, or if they are empty, // retrieve them from the credential store