abstract oidc factory

This commit is contained in:
kkb0318
2024-03-31 22:08:07 +09:00
parent d40d78ca98
commit d8fa1111dd
7 changed files with 130 additions and 41 deletions
+23 -12
View File
@@ -19,7 +19,6 @@ package controller
import ( import (
"context" "context"
awsclient "github.com/kkb0318/irsa-manager/internal/client"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime" ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client" "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 { func (r *IRSASetupReconciler) reconcile(ctx context.Context) error {
var discoveryContents selfhosted.OIDCIdPDiscoveryContents err := reconcileSelfhosted(ctx)
var discovery selfhosted.OIDCIdPDiscovery return err
var idp selfhosted.OIDCIdP }
func reconcileSelfhosted(ctx context.Context) error {
keyPair, err := selfhosted.CreateKeyPair() keyPair, err := selfhosted.CreateKeyPair()
if err != nil { if err != nil {
return err return err
@@ -69,16 +70,30 @@ func (r *IRSASetupReconciler) reconcile(ctx context.Context) error {
if err != nil { if err != nil {
return err return err
} }
discoveryContents = oidc.NewIdPDiscoveryContents(jwk, "issuerHostPath", "keys.json") // get from CRs
awsConfig, err := awsclient.NewAwsClient(ctx, "ap-northeast-1") 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 { if err != nil {
return err 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 { if err != nil {
return err return err
} }
err = discovery.CreateStorage() err = discovery.CreateStorage(ctx)
if err != nil { if err != nil {
return err return err
} }
@@ -86,10 +101,6 @@ func (r *IRSASetupReconciler) reconcile(ctx context.Context) error {
if err != nil { if err != nil {
return err return err
} }
idp, err = oidc.NewAwsIdP(awsConfig, discovery)
if err != nil {
return err
}
_, err = idp.Create(ctx) _, err = idp.Create(ctx)
if err != nil { if err != nil {
return err return err
+17 -6
View File
@@ -2,6 +2,17 @@ package selfhosted
import "context" 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 { type OIDCIdPDiscoveryContents interface {
Discovery() ([]byte, error) Discovery() ([]byte, error)
JWK() ([]byte, error) JWK() ([]byte, error)
@@ -9,13 +20,13 @@ type OIDCIdPDiscoveryContents interface {
} }
type OIDCIdPDiscovery interface { type OIDCIdPDiscovery interface {
CreateStorage() error CreateStorage(ctx context.Context) error
Upload(ctx context.Context, o OIDCIdPDiscoveryContents) error Upload(ctx context.Context, o OIDCIdPDiscoveryContents) error
Endpoint() string
} }
type OIDCIdP interface { type OIDCIdPFactory interface {
Create(ctx context.Context) (string, error) IssuerMeta() OIDCIssuerMeta
IsUpdate() (bool, error) IdP(i OIDCIssuerMeta) (OIDCIdP, error)
Update(ctx context.Context) error IdPDiscovery() OIDCIdPDiscovery
IdPDiscoveryContents(i OIDCIssuerMeta) OIDCIdPDiscoveryContents
} }
+42
View File
@@ -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)
}
+5 -5
View File
@@ -8,17 +8,17 @@ import (
) )
type AwsIdP struct { type AwsIdP struct {
iamClient *client.AwsIamClient iamClient *client.AwsIamClient
discovery selfhosted.OIDCIdPDiscovery 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() iamClient := awsConfig.IamCient()
return &AwsIdP{iamClient, discovery}, nil return &AwsIdP{iamClient, issuerMeta}, nil
} }
func (a *AwsIdP) Create(ctx context.Context) (string, error) { 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 { if err != nil {
return "", err return "", err
} }
@@ -16,14 +16,14 @@ type S3IdPDiscovery struct {
// NewS3IdPDiscovery initializes a new instance of S3IdPCreator with the specified AWS region and bucket name. // 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. // 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) s3Client := awsConfig.S3Cient(bucketName)
return &S3IdPDiscovery{s3Client}, nil return &S3IdPDiscovery{s3Client}
} }
// CreateStorage creates an S3 bucket // CreateStorage creates an S3 bucket
func (s *S3IdPDiscovery) CreateStorage() error { func (s *S3IdPDiscovery) CreateStorage(ctx context.Context) error {
err := s.s3Client.CreateBucket(context.TODO()) err := s.s3Client.CreateBucket(ctx)
if err != nil { if err != nil {
return fmt.Errorf("unable to create bucket, %w", err) 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 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())
}
@@ -8,9 +8,9 @@ import (
) )
type IdPDiscoveryContents struct { type IdPDiscoveryContents struct {
jwk *selfhosted.JWK jwk *selfhosted.JWK
issuerHostPath string issuerMeta selfhosted.OIDCIssuerMeta
jwksFileName string jwksFileName string
} }
type oidcDiscoveryConfiguration struct { type oidcDiscoveryConfiguration struct {
@@ -23,10 +23,14 @@ type oidcDiscoveryConfiguration struct {
ClaimsSupported []string `json:"claims_supported"` 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) { func (p *IdPDiscoveryContents) Discovery() ([]byte, error) {
oidcConfig := oidcDiscoveryConfiguration{ oidcConfig := oidcDiscoveryConfiguration{
Issuer: fmt.Sprintf("https://%s/", p.issuerHostPath), Issuer: fmt.Sprintf("%s/", p.issuerMeta.IssuerUrl()),
JWKSURI: fmt.Sprintf("https://%s/%s", p.issuerHostPath, p.jwksFileName), JWKSURI: fmt.Sprintf("%s/%s", p.issuerMeta.IssuerUrl(), p.jwksFileName),
AuthorizationEndpoint: "urn:kubernetes:programmatic_authorization", AuthorizationEndpoint: "urn:kubernetes:programmatic_authorization",
ResponseTypesSupported: []string{"id_token"}, ResponseTypesSupported: []string{"id_token"},
SubjectTypesSupported: []string{"public"}, SubjectTypesSupported: []string{"public"},
@@ -51,7 +55,3 @@ func (p *IdPDiscoveryContents) JWK() ([]byte, error) {
func (p *IdPDiscoveryContents) JWKsFileName() string { func (p *IdPDiscoveryContents) JWKsFileName() string {
return p.jwksFileName return p.jwksFileName
} }
func NewIdPDiscoveryContents(jwk *selfhosted.JWK, issuerHostPath, jwksFileName string) *IdPDiscoveryContents {
return &IdPDiscoveryContents{jwk, issuerHostPath, jwksFileName}
}
+30
View File
@@ -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())
}