Compare commits

...

4 Commits

Author SHA1 Message Date
Lio李歐 2c6ebdafde
Merge 441018cdd3 into 236ba5690e 2025-08-09 00:17:11 +02:00
Christophe 236ba5690e
Add archive notice to README (#3502) 2025-06-03 10:36:10 -04:00
Quan Zhang fa67e45814
chore: remove @zhangquan and @jeromeju from maintainer list (#3345) 2025-06-03 10:21:02 -04:00
Lionello Lunesu 441018cdd3 add Digital Ocean credentials helper 2024-06-10 14:00:03 -07:00
8 changed files with 164 additions and 2 deletions

View File

@ -1,2 +0,0 @@
Jerome Ju <jeromeju@google.com>
Quan Zhang <zhangquan@google.com>

View File

@ -1,3 +1,11 @@
# 🧊 This project is archived and no longer developed or maintained. 🧊
The code remains available for historic purposes.
The README as of the archival date remains unchanged below for historic purposes.
-----
# kaniko - Build Images In Kubernetes
## 🚨NOTE: kaniko is not an officially supported Google product🚨

1
go.mod
View File

@ -34,6 +34,7 @@ require (
)
require (
github.com/DefangLabs/docker-credential-digitalocean v0.0.0-20240610205821-a2ef21e94d2a
github.com/GoogleCloudPlatform/docker-credential-gcr/v2 v2.1.22
github.com/containerd/containerd v1.7.27
)

4
go.sum
View File

@ -68,6 +68,10 @@ github.com/Azure/go-autorest/tracing v0.6.1/go.mod h1:/3EgjbsjraOqiicERAeu3m7/z0
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs=
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/DefangLabs/docker-credential-digitalocean v0.0.0-20240610200406-4d010eb955c7 h1:jMHbuQDsR9b88eSR67RST0N6KzPw2AMAjU/7CMXI10o=
github.com/DefangLabs/docker-credential-digitalocean v0.0.0-20240610200406-4d010eb955c7/go.mod h1:CxvWG/LMHXIzKpqjwzHE2VOJmVV/37DJSCls+6Ldh2g=
github.com/DefangLabs/docker-credential-digitalocean v0.0.0-20240610205821-a2ef21e94d2a h1:4DjV2A5Cajan+V1jUi2UeQjq5CgWrXVVeC4hzs7aJfI=
github.com/DefangLabs/docker-credential-digitalocean v0.0.0-20240610205821-a2ef21e94d2a/go.mod h1:CxvWG/LMHXIzKpqjwzHE2VOJmVV/37DJSCls+6Ldh2g=
github.com/GoogleCloudPlatform/docker-credential-gcr/v2 v2.1.22 h1:HevuUpLsTedep2D6wnIp6AAJbVgP0BiVxaMt3HXeOyA=
github.com/GoogleCloudPlatform/docker-credential-gcr/v2 v2.1.22/go.mod h1:nzCpg7DFIIkQIZB3mdUPXVvqQ5f/GahA6xgWXTjnK7w=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 h1:ErKg/3iS1AKcTkf3yixlZ54f9U1rljCkQyEXWUnIUxc=

View File

@ -19,6 +19,7 @@ package creds
import (
"io"
do "github.com/DefangLabs/docker-credential-digitalocean/pkg/credhelper"
ecr "github.com/awslabs/amazon-ecr-credential-helper/ecr-login"
"github.com/chrismellard/docker-credential-acr-env/pkg/credhelper"
gitlab "github.com/ePirat/docker-credential-gitlabci/pkg/credhelper"
@ -34,5 +35,6 @@ func GetKeychain() authn.Keychain {
authn.NewKeychainFromHelper(ecr.NewECRHelper(ecr.WithLogger(io.Discard))),
authn.NewKeychainFromHelper(credhelper.NewACRCredentialsHelper()),
authn.NewKeychainFromHelper(gitlab.NewGitLabCredentialsHelper()),
authn.NewKeychainFromHelper(do.NewDigitalOceanCredentialHelper(do.WithReadWrite(), do.WithExpiry(3600))),
)
}

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Defang Software Labs
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,125 @@
package credhelper
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
"slices"
"strconv"
)
const (
doRegistry = "registry.digitalocean.com"
)
var (
apiEndpoint = "api.digitalocean.com"
client = http.DefaultClient
)
type DigitalOceanCredentialHelper struct {
// The duration in seconds that the returned registry credentials will be valid. If not set or 0, the credentials will not expire.
ExpirySeconds int
// By default, the registry credentials allow for read-only access. Set this query parameter to true to obtain read-write credentials.
ReadWrite bool
token string
}
type Option func(*DigitalOceanCredentialHelper)
// NewDigitalOceanCredentialHelper creates a new credential helper with the given options.
// By default, the API token is read from the DIGITALOCEAN_TOKEN environment variable,
// but it can be overridden with the WithToken option.
// The ExpirySeconds and ReadWrite options default to 0 (never) and false, respectively.
func NewDigitalOceanCredentialHelper(options ...Option) *DigitalOceanCredentialHelper {
do := &DigitalOceanCredentialHelper{
token: os.Getenv("DIGITALOCEAN_TOKEN"),
}
for _, option := range options {
option(do)
}
return do
}
func WithExpiry(seconds int) Option {
return func(d *DigitalOceanCredentialHelper) {
d.ExpirySeconds = seconds
}
}
func WithReadWrite() Option {
return func(d *DigitalOceanCredentialHelper) {
d.ReadWrite = true
}
}
func WithToken(token string) Option {
return func(d *DigitalOceanCredentialHelper) {
d.token = token
}
}
func (d DigitalOceanCredentialHelper) Get(serverURL string) (string, string, error) {
serverUrl, err := url.Parse("https://" + serverURL)
if err != nil {
return "", "", fmt.Errorf("failed to parse registry URL: %w", err)
}
if serverUrl.Hostname() != doRegistry {
return "", "", fmt.Errorf("not a Digital Ocean registry: %s", serverUrl.Hostname())
}
query := url.Values{}
if d.ExpirySeconds > 0 {
query.Set("expiry_seconds", strconv.Itoa(d.ExpirySeconds))
}
if d.ReadWrite {
query.Set("read_write", "true")
}
api := url.URL{
Scheme: "https",
Host: apiEndpoint,
Path: "/v2/registry/docker-credentials",
RawQuery: query.Encode(),
}
req, err := http.NewRequest("GET", api.String(), nil)
if err != nil {
return "", "", fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Accept", "application/json")
req.Header.Set("Authorization", "Bearer "+d.token)
res, err := client.Do(req)
if err != nil {
return "", "", fmt.Errorf("failed to get credentials from API: %w", err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return "", "", fmt.Errorf("failed to get credentials from API: %s", res.Status)
}
var creds dockerCredentialsResponse
if err := json.NewDecoder(res.Body).Decode(&creds); err != nil {
return "", "", fmt.Errorf("failed to decode credentials response: %w", err)
}
registry := serverUrl.Hostname()
auth := creds.Auths[registry].Auth
if len(auth) == 0 {
return "", "", fmt.Errorf("no credentials for registry %q", registry)
}
colon := slices.Index(auth, ':')
if colon == -1 {
return "", "", fmt.Errorf("invalid credentials")
}
user := string(auth[:colon])
pass := string(auth[colon+1:])
return user, pass, nil
}
type dockerCredentialsResponse struct {
Auths map[string]struct {
Auth []byte `json:"auth"`
} `json:"auths"`
}

3
vendor/modules.txt vendored
View File

@ -125,6 +125,9 @@ github.com/Azure/go-autorest/logger
# github.com/Azure/go-autorest/tracing v0.6.1
## explicit; go 1.15
github.com/Azure/go-autorest/tracing
# github.com/DefangLabs/docker-credential-digitalocean v0.0.0-20240610205821-a2ef21e94d2a
## explicit; go 1.21
github.com/DefangLabs/docker-credential-digitalocean/pkg/credhelper
# github.com/GoogleCloudPlatform/docker-credential-gcr/v2 v2.1.22
## explicit; go 1.21
github.com/GoogleCloudPlatform/docker-credential-gcr/v2