Skip to content

Commit

Permalink
Use Docker credentials file to log in to registry (#461)
Browse files Browse the repository at this point in the history
* Do not make registry Username and Password required

When we obtain authentication for Docker registries from the
environment, we only need to set the registry server field.

* Enable use of  Docker configuration for push registry authentication

We've used Docker api auth type to authenticate a Buildkit session.
For pushing to the registry, we can use this as well, using the registry
servername provided in the pulumi program as the lookup for which
registry to authenticate against.
If the program or provider config supplies credentials (username and
password), we use those preferentially.

* address review feedback

* hande errors

* appease linter
  • Loading branch information
guineveresaenger authored Jan 20, 2023
1 parent dedc353 commit a359430
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 57 deletions.
4 changes: 1 addition & 3 deletions provider/cmd/pulumi-resource-docker/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3161,9 +3161,7 @@
},
"type": "object",
"required": [
"server",
"username",
"password"
"server"
]
}
},
Expand Down
36 changes: 29 additions & 7 deletions provider/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,15 +175,37 @@ func (p *dockerNativeProvider) dockerBuild(ctx context.Context,
if err != nil {
return "", nil, err
}
// Quick and dirty auth; we can also preconfigure the client itself I believe
// TODO: use auth pattern as above to use default auth
var authConfig = types.AuthConfig{
Username: img.Registry.Username,
Password: img.Registry.Password,
ServerAddress: img.Registry.Server,

// authentication for registry push
// we check if the user set creds in the Pulumi program, and use those preferentially
var pushAuthConfig types.AuthConfig

if img.Registry.Username != "" && img.Registry.Password != "" {
pushAuthConfig.Username = img.Registry.Username
pushAuthConfig.Password = img.Registry.Password
pushAuthConfig.ServerAddress = img.Registry.Server
} else {
// send warning if user is attempting to use in-program credentials
if img.Registry.Username == "" && img.Registry.Password != "" {
msg := "username was not set, although password was; using host credentials file"
err = p.host.LogStatus(ctx, "warning", urn, msg)
if err != nil {
return "", nil, err
}
}
if img.Registry.Password == "" && img.Registry.Username != "" {
msg := "password was not set, although username was; using host credentials file"
err = p.host.LogStatus(ctx, "warning", urn, msg)
if err != nil {
return "", nil, err
}
}
// we push to the server declared in the program, using our auth configs from image build.
// if the program does not have a server declared, we will let the docker client error
pushAuthConfig = authConfigs[img.Registry.Server]
}

authConfigBytes, err := json.Marshal(authConfig)
authConfigBytes, err := json.Marshal(pushAuthConfig)

if err != nil {
return "", nil, errors.Wrap(err, "Error parsing authConfig")
Expand Down
2 changes: 1 addition & 1 deletion provider/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func Provider() tfbridge.ProviderInfo {
Secret: true,
},
},
Required: []string{"server", "username", "password"},
Required: []string{"server"},
},
},
dockerResource(dockerMod, "DockerBuild").String(): {
Expand Down
6 changes: 3 additions & 3 deletions sdk/dotnet/Inputs/RegistryArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace Pulumi.Docker.Inputs
/// </summary>
public sealed class RegistryArgs : global::Pulumi.ResourceArgs
{
[Input("password", required: true)]
[Input("password")]
private Input<string>? _password;

/// <summary>
Expand All @@ -40,8 +40,8 @@ public Input<string>? Password
/// <summary>
/// The username to authenticate to the registry
/// </summary>
[Input("username", required: true)]
public Input<string> Username { get; set; } = null!;
[Input("username")]
public Input<string>? Username { get; set; }

public RegistryArgs()
{
Expand Down
20 changes: 10 additions & 10 deletions sdk/go/docker/pulumiTypes.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 12 additions & 12 deletions sdk/java/src/main/java/com/pulumi/docker/inputs/RegistryArgs.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import com.pulumi.core.annotations.Import;
import java.lang.String;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nullable;


/**
Expand All @@ -21,15 +23,15 @@ public final class RegistryArgs extends com.pulumi.resources.ResourceArgs {
* The password to authenticate to the registry
*
*/
@Import(name="password", required=true)
private Output<String> password;
@Import(name="password")
private @Nullable Output<String> password;

/**
* @return The password to authenticate to the registry
*
*/
public Output<String> password() {
return this.password;
public Optional<Output<String>> password() {
return Optional.ofNullable(this.password);
}

/**
Expand All @@ -51,15 +53,15 @@ public Output<String> server() {
* The username to authenticate to the registry
*
*/
@Import(name="username", required=true)
private Output<String> username;
@Import(name="username")
private @Nullable Output<String> username;

/**
* @return The username to authenticate to the registry
*
*/
public Output<String> username() {
return this.username;
public Optional<Output<String>> username() {
return Optional.ofNullable(this.username);
}

private RegistryArgs() {}
Expand Down Expand Up @@ -94,7 +96,7 @@ public Builder(RegistryArgs defaults) {
* @return builder
*
*/
public Builder password(Output<String> password) {
public Builder password(@Nullable Output<String> password) {
$.password = password;
return this;
}
Expand Down Expand Up @@ -136,7 +138,7 @@ public Builder server(String server) {
* @return builder
*
*/
public Builder username(Output<String> username) {
public Builder username(@Nullable Output<String> username) {
$.username = username;
return this;
}
Expand All @@ -152,9 +154,7 @@ public Builder username(String username) {
}

public RegistryArgs build() {
$.password = Objects.requireNonNull($.password, "expected parameter 'password' to be non-null");
$.server = Objects.requireNonNull($.server, "expected parameter 'server' to be non-null");
$.username = Objects.requireNonNull($.username, "expected parameter 'username' to be non-null");
return $;
}
}
Expand Down
4 changes: 2 additions & 2 deletions sdk/nodejs/types/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,15 +380,15 @@ export interface Registry {
/**
* The password to authenticate to the registry
*/
password: pulumi.Input<string>;
password?: pulumi.Input<string>;
/**
* The URL of the Docker registry server
*/
server: pulumi.Input<string>;
/**
* The username to authenticate to the registry
*/
username: pulumi.Input<string>;
username?: pulumi.Input<string>;
}

export interface RegistryImageBuild {
Expand Down
40 changes: 21 additions & 19 deletions sdk/python/pulumi_docker/_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -4196,30 +4196,20 @@ def target(self, value: Optional[pulumi.Input[str]]):
@pulumi.input_type
class RegistryArgs:
def __init__(__self__, *,
password: pulumi.Input[str],
server: pulumi.Input[str],
username: pulumi.Input[str]):
password: Optional[pulumi.Input[str]] = None,
username: Optional[pulumi.Input[str]] = None):
"""
Describes a Docker container registry
:param pulumi.Input[str] password: The password to authenticate to the registry
:param pulumi.Input[str] server: The URL of the Docker registry server
:param pulumi.Input[str] password: The password to authenticate to the registry
:param pulumi.Input[str] username: The username to authenticate to the registry
"""
pulumi.set(__self__, "password", password)
pulumi.set(__self__, "server", server)
pulumi.set(__self__, "username", username)

@property
@pulumi.getter
def password(self) -> pulumi.Input[str]:
"""
The password to authenticate to the registry
"""
return pulumi.get(self, "password")

@password.setter
def password(self, value: pulumi.Input[str]):
pulumi.set(self, "password", value)
if password is not None:
pulumi.set(__self__, "password", password)
if username is not None:
pulumi.set(__self__, "username", username)

@property
@pulumi.getter
Expand All @@ -4235,14 +4225,26 @@ def server(self, value: pulumi.Input[str]):

@property
@pulumi.getter
def username(self) -> pulumi.Input[str]:
def password(self) -> Optional[pulumi.Input[str]]:
"""
The password to authenticate to the registry
"""
return pulumi.get(self, "password")

@password.setter
def password(self, value: Optional[pulumi.Input[str]]):
pulumi.set(self, "password", value)

@property
@pulumi.getter
def username(self) -> Optional[pulumi.Input[str]]:
"""
The username to authenticate to the registry
"""
return pulumi.get(self, "username")

@username.setter
def username(self, value: pulumi.Input[str]):
def username(self, value: Optional[pulumi.Input[str]]):
pulumi.set(self, "username", value)


0 comments on commit a359430

Please sign in to comment.