Skip to content

Commit

Permalink
chore(refactor): do not create temporary file when dealing with conta…
Browse files Browse the repository at this point in the history
…iner registry credentials (#940)
  • Loading branch information
programmer04 authored Jan 15, 2025
1 parent 8c664a0 commit 77c48f5
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 75 deletions.
6 changes: 3 additions & 3 deletions controller/kongplugininstallation/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"oras.land/oras-go/v2/registry/remote/credentials"
orascreds "oras.land/oras-go/v2/registry/remote/credentials"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -99,7 +99,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
}

log.Trace(logger, "managing KongPluginInstallation resource")
var credentialsStore credentials.Store
var credentialsStore orascreds.Store
if kpi.Spec.ImagePullSecretRef != nil {
log.Trace(logger, "getting secret for KongPluginInstallation resource")
kpiNamespace := gatewayv1.Namespace(kpi.Namespace)
Expand Down Expand Up @@ -142,7 +142,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
)
}
var err error
credentialsStore, err = image.CredentialsStoreFromString(string(secretData))
credentialsStore, err = orascreds.NewMemoryStoreFromDockerConfig(secretData)
if err != nil {
return ctrl.Result{}, setStatusConditionFailedForKongPluginInstallation(ctx, r.Client, &kpi, fmt.Sprintf("can't parse secret: %q data: %s", secretNN, err))
}
Expand Down
21 changes: 0 additions & 21 deletions controller/kongplugininstallation/image/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"errors"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"sync"
Expand Down Expand Up @@ -118,26 +117,6 @@ func FetchPlugin(ctx context.Context, imageURL string, credentialsStore credenti
return extractKongPluginFromLayer(contentOfLayerWithPlugin)
}

// CredentialsStoreFromString expects content of typical configuration as a string, described
// in https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry
// and returns credentials.Store.
// This is typical way how private registries are used with Docker and Kubernetes.
func CredentialsStoreFromString(s string) (credentials.Store, error) {
// TODO: Now we create temporary file, which is not great and should be changed,
// but it's the only way to use credentials.NewFileStore(...) which robustly
// parses config.json (format used by Docker and Kubernetes).
tmpFile, err := os.CreateTemp("", "credentials")
if err != nil {
return nil, fmt.Errorf("failed to create temporary file: %w", err)
}
defer os.Remove(tmpFile.Name())
defer tmpFile.Close()
if _, err = tmpFile.WriteString(s); err != nil {
return nil, fmt.Errorf("failed to write credentials to file: %w", err)
}
return credentials.NewFileStore(tmpFile.Name())
}

type sizeLimitBytes int64

func (sl sizeLimitBytes) int64() int64 {
Expand Down
50 changes: 2 additions & 48 deletions controller/kongplugininstallation/image/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,58 +5,12 @@ import (
"testing"

"github.com/stretchr/testify/require"
"oras.land/oras-go/v2/registry/remote/auth"
"oras.land/oras-go/v2/registry/remote/credentials"
orascreds "oras.land/oras-go/v2/registry/remote/credentials"

"github.com/kong/gateway-operator/controller/kongplugininstallation/image"
"github.com/kong/gateway-operator/test/integration"
)

func TestCredentialsStoreFromString(t *testing.T) {
testCases := []struct {
name string
credentials string
expectedErrorMsg string
expectedCredentials func(t *testing.T, cs credentials.Store)
}{
{
name: "invalid credentials",
credentials: "foo",
expectedErrorMsg: "invalid config format:",
},
{
name: "valid credentials",
// Field auth is base64 encoded "test:test".
credentials: `
{
"auths": {
"ghcr.io": {
"auth": "dGVzdDp0ZXN0"
}
}
}`,
expectedCredentials: func(t *testing.T, cs credentials.Store) {
t.Helper()
require.NotNil(t, cs)
c, err := cs.Get(context.Background(), "ghcr.io")
require.NoError(t, err)
require.Equal(t, auth.Credential{Username: "test", Password: "test", RefreshToken: "", AccessToken: ""}, c)
},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
credsStore, err := image.CredentialsStoreFromString(tc.credentials)
if tc.expectedCredentials != nil {
tc.expectedCredentials(t, credsStore)
} else {
require.ErrorContains(t, err, tc.expectedErrorMsg)
}
})
}
}

func TestFetchPluginContent(t *testing.T) {
t.Log("This test accesses container registries on public internet")

Expand Down Expand Up @@ -94,7 +48,7 @@ func TestFetchPluginContent(t *testing.T) {
t.Skip("skipping - no credentials provided")
}

credsStore, err := image.CredentialsStoreFromString(credentials)
credsStore, err := orascreds.NewMemoryStoreFromDockerConfig([]byte(credentials))
require.NoError(t, err)

plugin, err := image.FetchPlugin(
Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ require (
k8s.io/apimachinery v0.32.0
k8s.io/client-go v0.32.0
k8s.io/kubernetes v1.32.0
oras.land/oras-go/v2 v2.5.0
// TODO: Use official release when
// https://github.com/oras-project/oras-go/pull/850 becomes part of it.
oras.land/oras-go/v2 v2.5.1-0.20250115103459-a15da41d19be
sigs.k8s.io/controller-runtime v0.19.4
sigs.k8s.io/gateway-api v1.2.1
sigs.k8s.io/kustomize/api v0.19.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -696,8 +696,8 @@ k8s.io/kubernetes v1.32.0 h1:4BDBWSolqPrv8GC3YfZw0CJvh5kA1TPnoX0FxDVd+qc=
k8s.io/kubernetes v1.32.0/go.mod h1:tiIKO63GcdPRBHW2WiUFm3C0eoLczl3f7qi56Dm1W8I=
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
oras.land/oras-go/v2 v2.5.0 h1:o8Me9kLY74Vp5uw07QXPiitjsw7qNXi8Twd+19Zf02c=
oras.land/oras-go/v2 v2.5.0/go.mod h1:z4eisnLP530vwIOUOJeBIj0aGI0L1C3d53atvCBqZHg=
oras.land/oras-go/v2 v2.5.1-0.20250115103459-a15da41d19be h1:KPk9UtQY1BLUOKJcQlIowjZRFofJxPNbD9hEaDnFMIs=
oras.land/oras-go/v2 v2.5.1-0.20250115103459-a15da41d19be/go.mod h1:ecS2SG90/ztmqyrxF98+K4Uxq88AqdpZti6DP3g3FZc=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0 h1:CPT0ExVicCzcpeN4baWEV2ko2Z/AsiZgEdwgcfwLgMo=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
sigs.k8s.io/controller-runtime v0.19.4 h1:SUmheabttt0nx8uJtoII4oIP27BVVvAKFvdvGFwV/Qo=
Expand Down

0 comments on commit 77c48f5

Please sign in to comment.