From d8fa1111dd98b39f890f348da5b81047c4ff8735 Mon Sep 17 00:00:00 2001 From: kkb0318 Date: Sun, 31 Mar 2024 22:08:07 +0900 Subject: [PATCH] abstract oidc factory --- internal/controller/irsasetup_controller.go | 35 ++++++++++------ internal/selfhosted/oidc.go | 23 +++++++--- internal/selfhosted/oidc/factory.go | 42 +++++++++++++++++++ internal/selfhosted/oidc/id_provider.go | 10 ++--- .../selfhosted/oidc/id_provider_discovery.go | 13 ++---- .../oidc/id_provider_discovery_contents.go | 18 ++++---- internal/selfhosted/oidc/issuer_meta.go | 30 +++++++++++++ 7 files changed, 130 insertions(+), 41 deletions(-) create mode 100644 internal/selfhosted/oidc/factory.go create mode 100644 internal/selfhosted/oidc/issuer_meta.go diff --git a/internal/controller/irsasetup_controller.go b/internal/controller/irsasetup_controller.go index 3486ed3..fef8227 100644 --- a/internal/controller/irsasetup_controller.go +++ b/internal/controller/irsasetup_controller.go @@ -19,7 +19,6 @@ package controller import ( "context" - awsclient "github.com/kkb0318/irsa-manager/internal/client" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -58,9 +57,11 @@ func (r *IRSASetupReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( } func (r *IRSASetupReconciler) reconcile(ctx context.Context) error { - var discoveryContents selfhosted.OIDCIdPDiscoveryContents - var discovery selfhosted.OIDCIdPDiscovery - var idp selfhosted.OIDCIdP + err := reconcileSelfhosted(ctx) + return err +} + +func reconcileSelfhosted(ctx context.Context) error { keyPair, err := selfhosted.CreateKeyPair() if err != nil { return err @@ -69,16 +70,30 @@ func (r *IRSASetupReconciler) reconcile(ctx context.Context) error { if err != nil { return err } - discoveryContents = oidc.NewIdPDiscoveryContents(jwk, "issuerHostPath", "keys.json") - awsConfig, err := awsclient.NewAwsClient(ctx, "ap-northeast-1") + // get from CRs + region := "ap-northeast-1" + bucketName := "my-bucket-name" + jwksFileName := "keys.json" + var factory selfhosted.OIDCIdPFactory + + factory, err = oidc.NewAwsS3IdpFactory( + ctx, + region, + bucketName, + jwk, + jwksFileName, + ) if err != nil { return err } - discovery, err = oidc.NewS3IdPDiscovery(awsConfig, "my-bucket-name") + issuerMeta := factory.IssuerMeta() + discovery := factory.IdPDiscovery() + discoveryContents := factory.IdPDiscoveryContents(issuerMeta) + idp, err := factory.IdP(issuerMeta) if err != nil { return err } - err = discovery.CreateStorage() + err = discovery.CreateStorage(ctx) if err != nil { return err } @@ -86,10 +101,6 @@ func (r *IRSASetupReconciler) reconcile(ctx context.Context) error { if err != nil { return err } - idp, err = oidc.NewAwsIdP(awsConfig, discovery) - if err != nil { - return err - } _, err = idp.Create(ctx) if err != nil { return err diff --git a/internal/selfhosted/oidc.go b/internal/selfhosted/oidc.go index 9a4ee6e..8c77fa7 100644 --- a/internal/selfhosted/oidc.go +++ b/internal/selfhosted/oidc.go @@ -2,6 +2,17 @@ package selfhosted import "context" +type OIDCIssuerMeta interface { + IssuerHostPath() string + IssuerUrl() string +} + +type OIDCIdP interface { + Create(ctx context.Context) (string, error) + IsUpdate() (bool, error) + Update(ctx context.Context) error +} + type OIDCIdPDiscoveryContents interface { Discovery() ([]byte, error) JWK() ([]byte, error) @@ -9,13 +20,13 @@ type OIDCIdPDiscoveryContents interface { } type OIDCIdPDiscovery interface { - CreateStorage() error + CreateStorage(ctx context.Context) error Upload(ctx context.Context, o OIDCIdPDiscoveryContents) error - Endpoint() string } -type OIDCIdP interface { - Create(ctx context.Context) (string, error) - IsUpdate() (bool, error) - Update(ctx context.Context) error +type OIDCIdPFactory interface { + IssuerMeta() OIDCIssuerMeta + IdP(i OIDCIssuerMeta) (OIDCIdP, error) + IdPDiscovery() OIDCIdPDiscovery + IdPDiscoveryContents(i OIDCIssuerMeta) OIDCIdPDiscoveryContents } diff --git a/internal/selfhosted/oidc/factory.go b/internal/selfhosted/oidc/factory.go new file mode 100644 index 0000000..f95c50d --- /dev/null +++ b/internal/selfhosted/oidc/factory.go @@ -0,0 +1,42 @@ +package oidc + +import ( + "context" + + awsclient "github.com/kkb0318/irsa-manager/internal/client" + "github.com/kkb0318/irsa-manager/internal/selfhosted" +) + +type AwsS3IdPFactory struct { + region string + bucketName string + awsConfig *awsclient.AwsConfig + jwk *selfhosted.JWK + jwksFileName string +} + +func NewAwsS3IdpFactory(ctx context.Context, region, bucketName string, jwk *selfhosted.JWK, jwksFileName string) (*AwsS3IdPFactory, error) { + awsConfig, err := awsclient.NewAwsClient(ctx, region) + if err != nil { + return nil, err + } + return &AwsS3IdPFactory{ + region, + bucketName, + awsConfig, + jwk, + jwksFileName, + }, nil +} + +func (f *AwsS3IdPFactory) IssuerMeta() selfhosted.OIDCIssuerMeta { + return NewS3IssuerMeta(f.region, f.bucketName) +} + +func (f *AwsS3IdPFactory) IdP(i selfhosted.OIDCIssuerMeta) (selfhosted.OIDCIdP, error) { + return NewAwsIdP(f.awsConfig, i) +} + +func (f *AwsS3IdPFactory) IdPDiscovery() selfhosted.OIDCIdPDiscovery { + return NewS3IdPDiscovery(f.awsConfig, f.bucketName) +} diff --git a/internal/selfhosted/oidc/id_provider.go b/internal/selfhosted/oidc/id_provider.go index 122ba95..a734df3 100644 --- a/internal/selfhosted/oidc/id_provider.go +++ b/internal/selfhosted/oidc/id_provider.go @@ -8,17 +8,17 @@ import ( ) type AwsIdP struct { - iamClient *client.AwsIamClient - discovery selfhosted.OIDCIdPDiscovery + iamClient *client.AwsIamClient + issuerMeta selfhosted.OIDCIssuerMeta } -func NewAwsIdP(awsConfig *client.AwsConfig, discovery selfhosted.OIDCIdPDiscovery) (*AwsIdP, error) { +func NewAwsIdP(awsConfig *client.AwsConfig, issuerMeta selfhosted.OIDCIssuerMeta) (*AwsIdP, error) { iamClient := awsConfig.IamCient() - return &AwsIdP{iamClient, discovery}, nil + return &AwsIdP{iamClient, issuerMeta}, nil } func (a *AwsIdP) Create(ctx context.Context) (string, error) { - arn, err := a.iamClient.CreateOIDCProvider(ctx, a.discovery.Endpoint()) + arn, err := a.iamClient.CreateOIDCProvider(ctx, a.issuerMeta.IssuerUrl()) if err != nil { return "", err } diff --git a/internal/selfhosted/oidc/id_provider_discovery.go b/internal/selfhosted/oidc/id_provider_discovery.go index d634284..793615d 100644 --- a/internal/selfhosted/oidc/id_provider_discovery.go +++ b/internal/selfhosted/oidc/id_provider_discovery.go @@ -16,14 +16,14 @@ type S3IdPDiscovery struct { // NewS3IdPDiscovery initializes a new instance of S3IdPCreator with the specified AWS region and bucket name. // This function attempts to create an AWS client configured for the specified region. -func NewS3IdPDiscovery(awsConfig *client.AwsConfig, bucketName string) (*S3IdPDiscovery, error) { +func NewS3IdPDiscovery(awsConfig *client.AwsConfig, bucketName string) *S3IdPDiscovery { s3Client := awsConfig.S3Cient(bucketName) - return &S3IdPDiscovery{s3Client}, nil + return &S3IdPDiscovery{s3Client} } // CreateStorage creates an S3 bucket -func (s *S3IdPDiscovery) CreateStorage() error { - err := s.s3Client.CreateBucket(context.TODO()) +func (s *S3IdPDiscovery) CreateStorage(ctx context.Context) error { + err := s.s3Client.CreateBucket(ctx) if err != nil { return fmt.Errorf("unable to create bucket, %w", err) } @@ -60,8 +60,3 @@ func (s *S3IdPDiscovery) Upload(ctx context.Context, o selfhosted.OIDCIdPDiscove return nil } -// Endpoint constructs the URL path for the OIDC issuer based on the provided AWS region and bucket name. -// This utility function generates the expected host path for accessing the OIDC configuration stored in an S3 bucket. -func (p *S3IdPDiscovery) Endpoint() string { - return fmt.Sprintf("s3-%s.amazonaws.com/%s", p.s3Client.Region(), p.s3Client.BucketName()) -} diff --git a/internal/selfhosted/oidc/id_provider_discovery_contents.go b/internal/selfhosted/oidc/id_provider_discovery_contents.go index bf89e4a..35c0bbe 100644 --- a/internal/selfhosted/oidc/id_provider_discovery_contents.go +++ b/internal/selfhosted/oidc/id_provider_discovery_contents.go @@ -8,9 +8,9 @@ import ( ) type IdPDiscoveryContents struct { - jwk *selfhosted.JWK - issuerHostPath string - jwksFileName string + jwk *selfhosted.JWK + issuerMeta selfhosted.OIDCIssuerMeta + jwksFileName string } type oidcDiscoveryConfiguration struct { @@ -23,10 +23,14 @@ type oidcDiscoveryConfiguration struct { ClaimsSupported []string `json:"claims_supported"` } +func NewIdPDiscoveryContents(jwk *selfhosted.JWK, issuerMeta selfhosted.OIDCIssuerMeta, jwksFileName string) *IdPDiscoveryContents { + return &IdPDiscoveryContents{jwk, issuerMeta, jwksFileName} +} + func (p *IdPDiscoveryContents) Discovery() ([]byte, error) { oidcConfig := oidcDiscoveryConfiguration{ - Issuer: fmt.Sprintf("https://%s/", p.issuerHostPath), - JWKSURI: fmt.Sprintf("https://%s/%s", p.issuerHostPath, p.jwksFileName), + Issuer: fmt.Sprintf("%s/", p.issuerMeta.IssuerUrl()), + JWKSURI: fmt.Sprintf("%s/%s", p.issuerMeta.IssuerUrl(), p.jwksFileName), AuthorizationEndpoint: "urn:kubernetes:programmatic_authorization", ResponseTypesSupported: []string{"id_token"}, SubjectTypesSupported: []string{"public"}, @@ -51,7 +55,3 @@ func (p *IdPDiscoveryContents) JWK() ([]byte, error) { func (p *IdPDiscoveryContents) JWKsFileName() string { return p.jwksFileName } - -func NewIdPDiscoveryContents(jwk *selfhosted.JWK, issuerHostPath, jwksFileName string) *IdPDiscoveryContents { - return &IdPDiscoveryContents{jwk, issuerHostPath, jwksFileName} -} diff --git a/internal/selfhosted/oidc/issuer_meta.go b/internal/selfhosted/oidc/issuer_meta.go new file mode 100644 index 0000000..d66f816 --- /dev/null +++ b/internal/selfhosted/oidc/issuer_meta.go @@ -0,0 +1,30 @@ +package oidc + +import ( + "fmt" +) + +type IssuerMeta interface { + IssuerHostPath() string + IssuerUrl() string +} + +type S3IssuerMeta struct { + region string + bucketName string +} + +func NewS3IssuerMeta(region, bucketName string) *S3IssuerMeta { + return &S3IssuerMeta{region, bucketName} +} + +func (i *S3IssuerMeta) IssuerHostPath() string { + return fmt.Sprintf("s3-%s.amazonaws.com/%s", i.region, i.bucketName) +} + +// IssuerUrl constructs the URL path for the OIDC issuer based on the provided AWS region and bucket name. +// This utility function generates the expected host path for accessing the OIDC configuration stored in an S3 bucket. +func (i *S3IssuerMeta) IssuerUrl() string { + return fmt.Sprintf("https://%s", i. + IssuerHostPath()) +}