mirror of
https://github.com/storytold/irsa-manager.git
synced 2026-10-09 00:09:43 +00:00
abstract oidc factory
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
@@ -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}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user