diff --git a/pkg/cmd/join/cmd.go b/pkg/cmd/join/cmd.go index 92509385..21560bbe 100644 --- a/pkg/cmd/join/cmd.go +++ b/pkg/cmd/join/cmd.go @@ -17,6 +17,7 @@ var example = ` %[1]s join --hub-token --hub-apiserver --cluster-name --mode hosted --managed-cluster-kubeconfig # join a cluster to the hub while the hub provided no valid CA data in kube-public namespace %[1]s join --hub-token --hub-apiserver --cluster-name --ca-file +%[1]s join --hub-token --hub-apiserver --cluster-name --registration-auth awsirsa --hub-cluster-arn arn:aws:eks:us-west-2:123456789012:cluster/hub-cluster-1 ` // NewCmd ... @@ -77,5 +78,7 @@ func NewCmd(clusteradmFlags *genericclioptionsclusteradm.ClusteradmFlags, stream cmd.Flags().BoolVar(&o.createNameSpace, "create-namespace", true, "If true, create the operator namespace(open-cluster-management) and the agent namespace(open-cluster-management-agent for Default mode, for Hosted mode), otherwise use existing one") cmd.Flags().BoolVar(&o.enableSyncLabels, "enable-sync-labels", false, "If true, sync the labels from klusterlet to all agent resources.") cmd.Flags().Int32Var(&o.clientCertExpirationSeconds, "client-cert-expiration-seconds", 31536000, "clientCertExpirationSeconds represents the seconds of a client certificate to expire.") + cmd.Flags().StringVar(&o.registrationAuth, "registration-auth", "", "The type of authentication to use for registering and authenticating with hub") + cmd.Flags().StringVar(&o.hubClusterArn, "hub-cluster-arn", "", "The arn of the hub cluster(i.e. EKS cluster) to which managed-cluster will join") return cmd } diff --git a/pkg/cmd/join/exec.go b/pkg/cmd/join/exec.go index 378d97cc..e571ad42 100644 --- a/pkg/cmd/join/exec.go +++ b/pkg/cmd/join/exec.go @@ -7,6 +7,7 @@ import ( "crypto/x509" "encoding/pem" "fmt" + gherrors "github.com/pkg/errors" "os" "reflect" "strings" @@ -49,8 +50,9 @@ import ( const ( AgentNamespacePrefix = "open-cluster-management-" - OperatorNamesapce = "open-cluster-management" - DefaultOperatorName = "klusterlet" + OperatorNamesapce = "open-cluster-management" + DefaultOperatorName = "klusterlet" + AwsIrsaAuthentication = "awsirsa" ) func format(s string) string { @@ -148,6 +150,24 @@ func (o *Options) complete(cmd *cobra.Command, args []string) (err error) { genericclioptionsclusteradm.SpokeMutableFeatureGate, ocmfeature.DefaultSpokeRegistrationFeatureGates), ClientCertExpirationSeconds: o.clientCertExpirationSeconds, } + + // set registration auth type + if o.registrationAuth == AwsIrsaAuthentication { + rawConfig, err := o.ClusteradmFlags.KubectlFactory.ToRawKubeConfigLoader().RawConfig() + if err != nil { + klog.Errorf("unable to load managedcluster kubeconfig: %v", err) + return err + } + + o.klusterletChartConfig.Klusterlet.RegistrationConfiguration.RegistrationDriver = operatorv1.RegistrationDriver{ + AuthType: o.registrationAuth, + AwsIrsa: &operatorv1.AwsIrsa{ + HubClusterArn: o.hubClusterArn, + ManagedClusterArn: rawConfig.Contexts[rawConfig.CurrentContext].Cluster, + }, + } + } + o.klusterletChartConfig.Klusterlet.WorkConfiguration = operatorv1.WorkAgentConfiguration{ FeatureGates: genericclioptionsclusteradm.ConvertToFeatureGateAPI( genericclioptionsclusteradm.SpokeMutableFeatureGate, ocmfeature.DefaultSpokeWorkFeatureGates), @@ -293,6 +313,10 @@ func (o *Options) validate() error { return err } + if (o.registrationAuth == AwsIrsaAuthentication) && (o.hubClusterArn == "") { + return gherrors.New("hubClusterArn cannot be empty if registrationAuth type is awsirsa") + } + return nil } diff --git a/pkg/cmd/join/options.go b/pkg/cmd/join/options.go index 114460c2..f67a821b 100644 --- a/pkg/cmd/join/options.go +++ b/pkg/cmd/join/options.go @@ -86,6 +86,12 @@ type Options struct { enableSyncLabels bool clientCertExpirationSeconds int32 + + // The type of authentication to use for registering and authenticating with hub + registrationAuth string + + // The arn of hub cluster(i.e. EKS) to which managed-cluster will join + hubClusterArn string } func newOptions(clusteradmFlags *genericclioptionsclusteradm.ClusteradmFlags, streams genericiooptions.IOStreams) *Options {