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
  • Loading branch information
programmer04 committed Jan 9, 2025
1 parent ea43fb9 commit 269eb4f
Show file tree
Hide file tree
Showing 5 changed files with 11 additions and 74 deletions.
7 changes: 4 additions & 3 deletions controller/kongplugininstallation/controller.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package kongplugininstallation

import (
"bytes"
"context"
"errors"
"fmt"
Expand All @@ -11,7 +12,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 +100,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 +143,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.NewReadOnlyFileStore(bytes.NewReader(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
51 changes: 3 additions & 48 deletions controller/kongplugininstallation/image/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,16 @@ package image_test

import (
"context"
"strings"
"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 +49,7 @@ func TestFetchPluginContent(t *testing.T) {
t.Skip("skipping - no credentials provided")
}

credsStore, err := image.CredentialsStoreFromString(credentials)
credsStore, err := orascreds.NewReadOnlyFileStore(strings.NewReader(credentials))
require.NoError(t, err)

plugin, err := image.FetchPlugin(
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ go 1.23.2
// This retraction is to prevent it from being used and from breaking builds of dependent projects.
retract v1.2.2

replace oras.land/oras-go/v2 => github.com/programmer04/oras-go/v2 v2.5.1-0.20250109105054-83d5c64b9a01

require (
github.com/Kong/sdk-konnect-go v0.1.18
github.com/Masterminds/semver v1.5.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
github.com/programmer04/oras-go/v2 v2.5.1-0.20250109105054-83d5c64b9a01 h1:xywm1lFq4n4HpBmEM2Wciq6R5MSg4CYTZlKnxFn1THU=
github.com/programmer04/oras-go/v2 v2.5.1-0.20250109105054-83d5c64b9a01/go.mod h1:ecS2SG90/ztmqyrxF98+K4Uxq88AqdpZti6DP3g3FZc=
github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI=
github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
Expand Down Expand Up @@ -687,8 +689,6 @@ 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=
sigs.k8s.io/controller-runtime v0.19.4 h1:SUmheabttt0nx8uJtoII4oIP27BVVvAKFvdvGFwV/Qo=
sigs.k8s.io/controller-runtime v0.19.4/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4=
sigs.k8s.io/gateway-api v1.2.1 h1:fZZ/+RyRb+Y5tGkwxFKuYuSRQHu9dZtbjenblleOLHM=
Expand Down

0 comments on commit 269eb4f

Please sign in to comment.