Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .harness/harness.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pipeline:
identifier: Run_1
spec:
connectorRef: Plugins_Docker_Hub_Connector
image: golang:1.24.11
image: golang:1.25.7
shell: Sh
command: go vet ./...
- step:
Expand All @@ -42,7 +42,7 @@ pipeline:
identifier: Run_2
spec:
connectorRef: Plugins_Docker_Hub_Connector
image: golang:1.24.11
image: golang:1.25.7
shell: Sh
command: go test -cover ./...
- parallel:
Expand Down Expand Up @@ -70,7 +70,7 @@ pipeline:
identifier: Build_Push
spec:
connectorRef: Plugins_Docker_Hub_Connector
image: golang:1.24.11
image: golang:1.25.7
shell: Sh
command: go build -a -tags netgo -o release/linux/amd64/drone-<+matrix.repo> ./cmd/drone-<+matrix.repo>
envVariables:
Expand Down Expand Up @@ -157,7 +157,7 @@ pipeline:
identifier: buildpush
spec:
connectorRef: Plugins_Docker_Hub_Connector
image: golang:1.24.11
image: golang:1.25.7
shell: Sh
command: go build -a -tags netgo -o release/linux/arm64/drone-<+matrix.repo> ./cmd/drone-<+matrix.repo>
envVariables:
Expand Down
79 changes: 41 additions & 38 deletions cmd/drone-acr/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"log/slog"
"net/http"
"net/url"
"os"
Expand All @@ -16,8 +17,6 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/joho/godotenv"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"

docker "github.com/drone-plugins/drone-docker"
azureutil "github.com/drone-plugins/drone-docker/internal/azure"
Expand Down Expand Up @@ -82,32 +81,35 @@ func main() {
if username == "" && password == "" {
// docker login credentials are not provided
var err error
username = defaultUsername
if idToken != "" && clientId != "" && tenantId != "" {
logrus.Debug("Using OIDC authentication flow")
var aadToken string
aadToken, err = azureutil.GetAADAccessTokenViaClientAssertion(context.Background(), tenantId, clientId, idToken, authorityHost)
if err != nil {
logrus.Fatal(err)
}
username = defaultUsername
if idToken != "" && clientId != "" && tenantId != "" {
slog.Debug("using OIDC authentication flow")
var aadToken string
aadToken, err = azureutil.GetAADAccessTokenViaClientAssertion(context.Background(), tenantId, clientId, idToken, authorityHost)
if err != nil {
slog.Error("failed to get AAD access token", "error", err)
os.Exit(1)
}
var p string
p, err = getPublicUrl(aadToken, registry, subscriptionId)
if err == nil {
publicUrl = p
} else {
fmt.Fprintf(os.Stderr, "failed to get public url with error: %s\n", err)
}
password, err = fetchACRToken(tenantId, aadToken, registry)
if err != nil {
logrus.Fatal(err)
}
} else {
password, publicUrl, err = getAuth(clientId, clientSecret, clientCert, tenantId, subscriptionId, registry)
if err != nil {
logrus.Fatal(err)
}
password, err = fetchACRToken(tenantId, aadToken, registry)
if err != nil {
slog.Error("failed to fetch ACR token", "error", err)
os.Exit(1)
}
} else {
password, publicUrl, err = getAuth(clientId, clientSecret, clientCert, tenantId, subscriptionId, registry)
if err != nil {
slog.Error("failed to get auth", "error", err)
os.Exit(1)
}
}
}

// must use the fully qualified repo name. If the
// repo name does not have the registry prefix we
Expand All @@ -133,7 +135,8 @@ func main() {
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
logrus.Fatal(err)
slog.Error("command execution failed", "error", err)
os.Exit(1)
}
}

Expand All @@ -153,26 +156,26 @@ func getAuth(clientId, clientSecret, clientCert, tenantId, subscriptionId, regis
if clientCert != "" {
err := setupACRCert(clientCert, acrCertPath)
if err != nil {
errors.Wrap(err, "failed to push setup cert file")
slog.Warn("failed to push setup cert file", "error", err)
}
}

// Get AZ env
if err := os.Setenv(clientIdEnv, clientId); err != nil {
return "", "", errors.Wrap(err, "failed to set env variable client Id")
return "", "", fmt.Errorf("failed to set env variable client Id: %w", err)
}
if err := os.Setenv(clientSecretKeyEnv, clientSecret); err != nil {
return "", "", errors.Wrap(err, "failed to set env variable client secret")
return "", "", fmt.Errorf("failed to set env variable client secret: %w", err)
}
if err := os.Setenv(tenantKeyEnv, tenantId); err != nil {
return "", "", errors.Wrap(err, "failed to set env variable tenant Id")
return "", "", fmt.Errorf("failed to set env variable tenant Id: %w", err)
}
if err := os.Setenv(certPathEnv, acrCertPath); err != nil {
return "", "", errors.Wrap(err, "failed to set env variable cert path")
return "", "", fmt.Errorf("failed to set env variable cert path: %w", err)
}
env, err := azidentity.NewEnvironmentCredential(nil)
if err != nil {
return "", "", errors.Wrap(err, "failed to get env credentials from azure")
return "", "", fmt.Errorf("failed to get env credentials from azure: %w", err)
}
os.Unsetenv(clientIdEnv)
os.Unsetenv(clientSecretKeyEnv)
Expand All @@ -185,7 +188,7 @@ func getAuth(clientId, clientSecret, clientCert, tenantId, subscriptionId, regis
}
aadToken, err := env.GetToken(context.Background(), policy)
if err != nil {
return "", "", errors.Wrap(err, "failed to fetch access token")
return "", "", fmt.Errorf("failed to fetch access token: %w", err)
}

// Get public URL for artifacts
Expand All @@ -198,7 +201,7 @@ func getAuth(clientId, clientSecret, clientCert, tenantId, subscriptionId, regis
// Fetch token
ACRToken, err := fetchACRToken(tenantId, aadToken.Token, registry)
if err != nil {
return "", "", errors.Wrap(err, "failed to fetch ACR token")
return "", "", fmt.Errorf("failed to fetch ACR token: %w", err)
}
return ACRToken, publicUrl, nil
}
Expand All @@ -213,34 +216,34 @@ func fetchACRToken(tenantId, token, registry string) (string, error) {
}
jsonResponse, err := http.PostForm(fmt.Sprintf("https://%s/oauth2/exchange", registry), formData)
if err != nil || jsonResponse == nil {
return "", errors.Wrap(err, "failed to fetch ACR token")
return "", fmt.Errorf("failed to fetch ACR token: %w", err)
}

// fetch token from response
var response map[string]interface{}
err = json.NewDecoder(jsonResponse.Body).Decode(&response)
if err != nil {
return "", errors.Wrap(err, "failed to decode oauth exchange response")
return "", fmt.Errorf("failed to decode oauth exchange response: %w", err)
}

// Parse the refresh_token from the response
if t, found := response["refresh_token"]; found {
if refreshToken, ok := t.(string); ok {
return refreshToken, nil
}
return "", errors.New("failed to cast refresh token from acr")
return "", fmt.Errorf("failed to cast refresh token from acr")
}
return "", errors.Wrap(err, "refresh token not found in response of oauth exchange call")
return "", fmt.Errorf("refresh token not found in response of oauth exchange call: %w", err)
}

func setupACRCert(cert, certPath string) error {
decoded, err := base64.StdEncoding.DecodeString(cert)
if err != nil {
return errors.Wrap(err, "failed to base64 decode ACR certificate")
return fmt.Errorf("failed to base64 decode ACR certificate: %w", err)
}
err = ioutil.WriteFile(certPath, decoded, 0644)
if err != nil {
return errors.Wrap(err, "failed to write ACR certificate")
return fmt.Errorf("failed to write ACR certificate: %w", err)
}
return nil
}
Expand All @@ -262,24 +265,24 @@ func getPublicUrl(token, registryUrl, subscriptionId string) (string, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Println(err)
return "", errors.Wrap(err, "failed to create request for getting container registry setting")
return "", fmt.Errorf("failed to create request for getting container registry setting: %w", err)
}

req.Header.Add("Authorization", "Bearer "+token)
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return "", errors.Wrap(err, "failed to send request for getting container registry setting")
return "", fmt.Errorf("failed to send request for getting container registry setting: %w", err)
}
defer res.Body.Close()

var response subscriptionUrlResponse
err = json.NewDecoder(res.Body).Decode(&response)
if err != nil {
return "", errors.Wrap(err, "failed to send request for getting container registry setting")
return "", fmt.Errorf("failed to send request for getting container registry setting: %w", err)
}
if len(response.Value) == 0 {
return "", errors.New("no id present for base url")
return "", fmt.Errorf("no id present for base url")
}
return basePublicUrl + encodeParam(response.Value[0].ID), nil
}
Expand Down
23 changes: 12 additions & 11 deletions cmd/drone-docker/main.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package main

import (
"log/slog"
"os"
"runtime"
"strings"

"github.com/dchest/uniuri"
"github.com/joho/godotenv"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"

docker "github.com/drone-plugins/drone-docker"
Expand Down Expand Up @@ -358,7 +358,8 @@ func main() {
}

if err := app.Run(os.Args); err != nil {
logrus.Fatal(err)
slog.Error("application error", "error", err)
os.Exit(1)
}
}

Expand Down Expand Up @@ -448,16 +449,16 @@ func run(c *cli.Context) error {
tag, err := docker.DefaultTagSuffix(
c.String("commit.ref"),
c.String("tags.suffix"),
)
if err != nil {
logrus.Printf("cannot build docker image for %s, invalid semantic version", c.String("commit.ref"))
return err
}
plugin.Build.Tags = tag
} else {
logrus.Printf("skipping automated docker build for %s", c.String("commit.ref"))
return nil
)
if err != nil {
slog.Error("cannot build docker image, invalid semantic version", "commit_ref", c.String("commit.ref"), "error", err)
return err
}
plugin.Build.Tags = tag
} else {
slog.Info("skipping automated docker build", "commit_ref", c.String("commit.ref"))
return nil
}
}

return plugin.Exec()
Expand Down
26 changes: 14 additions & 12 deletions cmd/drone-ecr/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"log"
"log/slog"
"os"
"os/exec"
"strconv"
Expand All @@ -18,7 +19,6 @@ import (
ecrtypes "github.com/aws/aws-sdk-go-v2/service/ecr/types"
"github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/joho/godotenv"
"github.com/sirupsen/logrus"

docker "github.com/drone-plugins/drone-docker"
)
Expand Down Expand Up @@ -130,24 +130,26 @@ func main() {
}
}

repositoryName := trimHostname(repo, registry)
for _, t := range tags {
exists, err := tagExists(ctx, svc, repositoryName, t)
if err != nil {
logrus.Fatalf("Error checking if image exists for tag %s: %v", t, err)
}
if exists {
logrus.Infof("%s:%s: Image tag exists. Skipping push.", repo, t)
os.Exit(0)
}
repositoryName := trimHostname(repo, registry)
for _, t := range tags {
exists, err := tagExists(ctx, svc, repositoryName, t)
if err != nil {
slog.Error("error checking if image exists for tag", "tag", t, "error", err)
os.Exit(1)
}
if exists {
slog.Info("image tag exists, skipping push", "repo", repo, "tag", t)
os.Exit(0)
}
}
}

cmd := exec.Command(docker.GetDroneDockerExecCmd())
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err = cmd.Run(); err != nil {
logrus.Fatal(err)
slog.Error("command execution failed", "error", err)
os.Exit(1)
}
}

Expand Down
11 changes: 7 additions & 4 deletions cmd/drone-gar/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/base64"
"fmt"
"log"
"log/slog"
"os"
"os/exec"
"path"
Expand All @@ -15,7 +16,6 @@ import (
"github.com/drone-plugins/drone-docker/internal/gcp"

"github.com/joho/godotenv"
"github.com/sirupsen/logrus"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
)
Expand Down Expand Up @@ -58,11 +58,13 @@ func loadConfig() Config {
if idToken != "" && projectId != "" && poolId != "" && providerId != "" && serviceAccountEmail != "" {
federalToken, err := gcp.GetFederalToken(idToken, projectId, poolId, providerId)
if err != nil {
logrus.Fatalf("Error (getFederalToken): %s", err)
slog.Error("getFederalToken error", "error", err)
os.Exit(1)
}
accessToken, err := gcp.GetGoogleCloudAccessToken(federalToken, serviceAccountEmail)
if err != nil {
logrus.Fatalf("Error (getGoogleCloudAccessToken): %s", err)
slog.Error("getGoogleCloudAccessToken error", "error", err)
os.Exit(1)
}
config.AccessToken = accessToken
} else {
Expand Down Expand Up @@ -110,7 +112,8 @@ func main() {
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
logrus.Fatal(err)
slog.Error("command execution failed", "error", err)
os.Exit(1)
}
}

Expand Down
Loading