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 (
"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
+17 -6
View File
@@ -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
}
+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 {
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
}
@@ -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())
}
@@ -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}
}
+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())
}