Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
Signed-off-by: alexey.komyakov <[email protected]>
  • Loading branch information
scaps1 committed Nov 5, 2024
1 parent 9e37e84 commit bbc7e53
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 44 deletions.
29 changes: 16 additions & 13 deletions pkg/providers/amazon/amazon.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,54 @@ package amazon
import (
"context"
"encoding/base64"
"fmt"
"strings"

"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/ecr"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/sirupsen/logrus"
)

type AwsECRProvider struct{}
type Provider struct{}

func NewECRProvider() *AwsECRProvider {
return &AwsECRProvider{}
func NewProvider() *Provider {
return &Provider{}
}

func (p *AwsECRProvider) GetAuthKeychain(ctx context.Context, registryStr string) (authn.Keychain, error) {
ecrClient, err := awsRegionalClient(ctx, parseECRDetails(registryStr))
func (p Provider) GetAuthKeychain(registryStr string) authn.Keychain {
ecrClient, err := awsRegionalClient(context.TODO(), parseECRDetails(registryStr))
if err != nil {
return nil, fmt.Errorf("error loading AWS config: %w", err)
logrus.Panic(err)
}

authTokenOutput, err := ecrClient.GetAuthorizationToken(ctx, &ecr.GetAuthorizationTokenInput{})
authTokenOutput, err := ecrClient.GetAuthorizationToken(context.TODO(), &ecr.GetAuthorizationTokenInput{})
if err != nil {
return nil, fmt.Errorf("error getting ECR authorization token: %w", err)
logrus.Panic(err)
}

if len(authTokenOutput.AuthorizationData) == 0 {
return nil, fmt.Errorf("no authorization data received from ECR")
logrus.Panic("no authorization data received from ECR")
return nil
}

authData := authTokenOutput.AuthorizationData[0]
decodedToken, err := base64.StdEncoding.DecodeString(*authData.AuthorizationToken)
if err != nil {
return nil, fmt.Errorf("error decoding authorization token: %w", err)
logrus.Panic("error decoding authorization token: %w", err)
return nil
}

credentials := strings.SplitN(string(decodedToken), ":", 2)
if len(credentials) != 2 {
return nil, fmt.Errorf("invalid authorization token format")
logrus.Panic("invalid authorization token format")
return nil
}
authConfig := authn.AuthConfig{
Username: credentials[0],
Password: credentials[1],
}
auth := authn.FromConfig(authConfig)
return &customKeychain{authenticator: auth}, nil
return &customKeychain{authenticator: auth}
}

func parseECRDetails(registryStr string) string {
Expand Down
29 changes: 29 additions & 0 deletions pkg/providers/k8s/k8s.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package k8s

import (
"context"
kubeauth "github.com/google/go-containerregistry/pkg/authn/kubernetes"
"github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"

"github.com/google/go-containerregistry/pkg/authn"
)

type Provider struct {
pullSecretsGetter func(image string) []corev1.Secret
}

func NewProvider(pullSecretsGetter func(image string) []corev1.Secret) *Provider {
return &Provider{
pullSecretsGetter: pullSecretsGetter,
}
}

func (p Provider) GetAuthKeychain(registryStr string) authn.Keychain {
dereferencedPullSecrets := p.pullSecretsGetter(registryStr)
kc, err := kubeauth.NewFromPullSecrets(context.TODO(), dereferencedPullSecrets)
if err != nil {
logrus.Panic(err)
}
return kc
}
24 changes: 18 additions & 6 deletions pkg/providers/provider.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
package providers

import (
"context"
"fmt"
corev1 "k8s.io/api/core/v1"
"strings"

"github.com/flant/k8s-image-availability-exporter/pkg/providers/amazon"
"github.com/flant/k8s-image-availability-exporter/pkg/providers/k8s"
"github.com/google/go-containerregistry/pkg/authn"
)

type Provider interface {
GetAuthKeychain(ctx context.Context, registryStr string) (authn.Keychain, error)
GetAuthKeychain(registryStr string) authn.Keychain
}

func GetProvider(registryStr string) (Provider, error) {
type ProviderRegistry map[string]Provider

func NewProviderChain(pullSecretsGetter func(image string) []corev1.Secret) ProviderRegistry {
return map[string]Provider{
"amazon": amazon.NewProvider(),
"k8s": k8s.NewProvider(pullSecretsGetter),
}
}

type ImagePullSecretsFunc func(image string) []corev1.Secret

func (p ProviderRegistry) GetAuthKeychain(registryStr string) authn.Keychain {
switch {
case strings.Contains(registryStr, "amazonaws.com"):
return amazon.NewECRProvider(), nil
return p["amazon"].GetAuthKeychain(registryStr)

default:
return nil, fmt.Errorf("unsupported registry")
return p["k8s"].GetAuthKeychain(registryStr)
}
}
29 changes: 15 additions & 14 deletions pkg/registry/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ import (
"crypto/x509"
"errors"
"fmt"
"net/http"
"os"
"regexp"
"strings"
"time"

"github.com/flant/k8s-image-availability-exporter/pkg/providers"
"github.com/flant/k8s-image-availability-exporter/pkg/version"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/v1/remote/transport"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/tools/cache"
"net/http"
"os"
"regexp"
"strings"
"time"

"github.com/prometheus/client_golang/prometheus"

Expand Down Expand Up @@ -69,6 +69,8 @@ type Checker struct {
kubeClient *kubernetes.Clientset

config registryCheckerConfig

providerRegistry providers.ProviderRegistry
}

func NewChecker(
Expand Down Expand Up @@ -254,6 +256,12 @@ func NewChecker(

rc.imageStore.RunGC(rc.controllerIndexers.GetContainerInfosForImage)

pullSecretsGetter := func(image string) []corev1.Secret {
return rc.controllerIndexers.GetImagePullSecrets(image)
}
pc := providers.NewProviderChain(pullSecretsGetter)
rc.providerRegistry = pc

return rc
}

Expand Down Expand Up @@ -291,7 +299,7 @@ imagesLoop:
}

func (rc *Checker) Check(imageName string) store.AvailabilityMode {
keyChain := rc.controllerIndexers.GetKeychainForImage(imageName)
keyChain := rc.providerRegistry.GetAuthKeychain(imageName)

log := logrus.WithField("image_name", imageName)
return rc.checkImageAvailability(log, imageName, keyChain)
Expand All @@ -316,13 +324,6 @@ func (rc *Checker) checkImageAvailability(log *logrus.Entry, imageName string, k
if err != nil {
return checkImageNameParseErr(log, err)
}
p, err := providers.GetProvider(ref.Context().RegistryStr())
if err == nil {
kChain, err := p.GetAuthKeychain(context.TODO(), ref.Context().RegistryStr())
if err == nil {
kc = kChain
}
}

imgErr := wait.ExponentialBackoff(wait.Backoff{
Duration: time.Second,
Expand Down
13 changes: 2 additions & 11 deletions pkg/registry/indexers.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package registry

import (
"context"
"fmt"
"slices"
"strings"

"github.com/flant/k8s-image-availability-exporter/pkg/store"
"github.com/google/go-containerregistry/pkg/authn"
kubeauth "github.com/google/go-containerregistry/pkg/authn/kubernetes"
"github.com/sirupsen/logrus"
appsv1 "k8s.io/api/apps/v1"
batchv1 "k8s.io/api/batch/v1"
Expand Down Expand Up @@ -257,7 +254,7 @@ func (ci ControllerIndexers) GetContainerInfosForImage(image string) (ret []stor
return
}

func (ci ControllerIndexers) GetKeychainForImage(image string) authn.Keychain {
func (ci ControllerIndexers) GetImagePullSecrets(image string) []corev1.Secret {
objs := ci.GetObjectsByImageIndex(image)

var refSet = map[string]struct{}{}
Expand All @@ -284,11 +281,5 @@ func (ci ControllerIndexers) GetKeychainForImage(image string) authn.Keychain {
if len(dereferencedPullSecrets) == 0 {
return nil
}

kc, err := kubeauth.NewFromPullSecrets(context.TODO(), dereferencedPullSecrets)
if err != nil {
logrus.Panic(err)
}

return kc
return dereferencedPullSecrets
}

0 comments on commit bbc7e53

Please sign in to comment.