Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue with register cluster #230

Merged
merged 1 commit into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 56 additions & 39 deletions internal/commands/generate/generate_kubeconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@ import (
rbacv1 "k8s.io/api/rbac/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"

logs "github.com/projectsveltos/libsveltos/lib/logsettings"
"github.com/projectsveltos/sveltosctl/internal/utils"
Expand All @@ -42,38 +46,58 @@ const (
Projectsveltos = "projectsveltos"
)

func GenerateKubeconfigForServiceAccount(ctx context.Context, namespace, serviceAccountName string,
func GenerateKubeconfigForServiceAccount(ctx context.Context, remoteRestConfig *rest.Config, namespace, serviceAccountName string,
expirationSeconds int, create, display bool, logger logr.Logger) (string, error) {

s := runtime.NewScheme()
err := clientgoscheme.AddToScheme(s)
if err != nil {
return "", err
}

var remoteClient client.Client
remoteClient, err = client.New(remoteRestConfig, client.Options{Scheme: s})
if err != nil {
return "", err
}

if create {
if err := createNamespace(ctx, namespace, logger); err != nil {
err = createNamespace(ctx, remoteClient, namespace, logger)
if err != nil {
return "", err
}
if err := createServiceAccount(ctx, namespace, serviceAccountName, logger); err != nil {
err = createServiceAccount(ctx, remoteClient, namespace, serviceAccountName, logger)
if err != nil {
return "", err
}
if err := createClusterRole(ctx, Projectsveltos, logger); err != nil {
err = createClusterRole(ctx, remoteClient, Projectsveltos, logger)
if err != nil {
return "", err
}
if err := createClusterRoleBinding(ctx, Projectsveltos, Projectsveltos, namespace, serviceAccountName, logger); err != nil {
err = createClusterRoleBinding(ctx, remoteClient, Projectsveltos, Projectsveltos, namespace,
serviceAccountName, logger)
if err != nil {
return "", err
}
} else {
if err := getNamespace(ctx, namespace); err != nil {
err = getNamespace(ctx, remoteClient, namespace)
if err != nil {
return "", err
}
if err := getServiceAccount(ctx, namespace, serviceAccountName); err != nil {
err = getServiceAccount(ctx, remoteClient, namespace, serviceAccountName)
if err != nil {
return "", err
}
}

tokenRequest, err := getServiceAccountTokenRequest(ctx, namespace, serviceAccountName, expirationSeconds, logger)
tokenRequest, err := getServiceAccountTokenRequest(ctx, remoteRestConfig, namespace, serviceAccountName,
expirationSeconds, logger)
if err != nil {
return "", err
}

logger.V(logs.LogDebug).Info("Get Kubeconfig from TokenRequest")
data := getKubeconfigFromToken(namespace, serviceAccountName, tokenRequest.Token)
data := getKubeconfigFromToken(remoteRestConfig, namespace, serviceAccountName, tokenRequest.Token)
if display {
//nolint: forbidigo // print kubeconfig
fmt.Println(data)
Expand All @@ -82,21 +106,20 @@ func GenerateKubeconfigForServiceAccount(ctx context.Context, namespace, service
return data, nil
}

func getNamespace(ctx context.Context, name string) error {
instance := utils.GetAccessInstance()
func getNamespace(ctx context.Context, remoteClient client.Client, name string) error {
currentNs := &corev1.Namespace{}
return instance.GetClient().Get(ctx, types.NamespacedName{Name: name}, currentNs)
return remoteClient.Get(ctx, types.NamespacedName{Name: name}, currentNs)
}

func createNamespace(ctx context.Context, name string, logger logr.Logger) error {
func createNamespace(ctx context.Context, remoteClient client.Client, name string, logger logr.Logger) error {
logger.V(logs.LogDebug).Info(fmt.Sprintf("Create namespace %s", name))
currentNs := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
}
instance := utils.GetAccessInstance()
err := instance.GetClient().Create(ctx, currentNs)

err := remoteClient.Create(ctx, currentNs)
if err != nil && !apierrors.IsAlreadyExists(err) {
logger.V(logs.LogDebug).Info(fmt.Sprintf("Failed to create Namespace %s: %v",
name, err))
Expand All @@ -106,15 +129,14 @@ func createNamespace(ctx context.Context, name string, logger logr.Logger) error
return nil
}

func getServiceAccount(ctx context.Context, namespace, name string) error {
instance := utils.GetAccessInstance()
func getServiceAccount(ctx context.Context, remoteClient client.Client, namespace, name string) error {
currentSA := &corev1.ServiceAccount{}
return instance.GetClient().Get(ctx,
return remoteClient.Get(ctx,
types.NamespacedName{Namespace: namespace, Name: name},
currentSA)
}

func createServiceAccount(ctx context.Context, namespace, name string,
func createServiceAccount(ctx context.Context, remoteClient client.Client, namespace, name string,
logger logr.Logger) error {

logger.V(logs.LogDebug).Info(fmt.Sprintf("Create serviceAccount %s/%s", namespace, name))
Expand All @@ -124,8 +146,8 @@ func createServiceAccount(ctx context.Context, namespace, name string,
Name: name,
},
}
instance := utils.GetAccessInstance()
err := instance.GetClient().Create(ctx, currentSA)

err := remoteClient.Create(ctx, currentSA)
if err != nil && !apierrors.IsAlreadyExists(err) {
logger.V(logs.LogDebug).Info(fmt.Sprintf("Failed to create ServiceAccount %s/%s: %v",
namespace, name, err))
Expand All @@ -135,8 +157,8 @@ func createServiceAccount(ctx context.Context, namespace, name string,
return nil
}

func createClusterRole(ctx context.Context, clusterRoleName string, logger logr.Logger) error {
instance := utils.GetAccessInstance()
func createClusterRole(ctx context.Context, remoteClient client.Client, clusterRoleName string,
logger logr.Logger) error {

logger.V(logs.LogDebug).Info(fmt.Sprintf("Create ClusterRole %s", clusterRoleName))
// Extends permission in addon-controller-role-extra
Expand All @@ -157,7 +179,7 @@ func createClusterRole(ctx context.Context, clusterRoleName string, logger logr.
},
}

err := instance.GetClient().Create(ctx, clusterrole)
err := remoteClient.Create(ctx, clusterrole)
if err != nil && !apierrors.IsAlreadyExists(err) {
logger.V(logs.LogDebug).Info(fmt.Sprintf("Failed to create ClusterRole %s: %v",
clusterRoleName, err))
Expand All @@ -167,11 +189,10 @@ func createClusterRole(ctx context.Context, clusterRoleName string, logger logr.
return nil
}

func createClusterRoleBinding(ctx context.Context, clusterRoleName, clusterRoleBindingName, serviceAccountNamespace, serviceAccountName string,
func createClusterRoleBinding(ctx context.Context, remoteClient client.Client,
clusterRoleName, clusterRoleBindingName, serviceAccountNamespace, serviceAccountName string,
logger logr.Logger) error {

instance := utils.GetAccessInstance()

logger.V(logs.LogDebug).Info(fmt.Sprintf("Create ClusterRoleBinding %s", clusterRoleBindingName))
clusterrolebinding := &rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Expand All @@ -191,7 +212,7 @@ func createClusterRoleBinding(ctx context.Context, clusterRoleName, clusterRoleB
},
},
}
err := instance.GetClient().Create(ctx, clusterrolebinding)
err := remoteClient.Create(ctx, clusterrolebinding)
if err != nil && !apierrors.IsAlreadyExists(err) {
logger.V(logs.LogDebug).Info(fmt.Sprintf("Failed to create clusterrolebinding %s: %v",
clusterRoleBindingName, err))
Expand All @@ -202,11 +223,9 @@ func createClusterRoleBinding(ctx context.Context, clusterRoleName, clusterRoleB
}

// getServiceAccountTokenRequest returns token for a serviceaccount
func getServiceAccountTokenRequest(ctx context.Context, serviceAccountNamespace, serviceAccountName string,
func getServiceAccountTokenRequest(ctx context.Context, remoteRestConfig *rest.Config, serviceAccountNamespace, serviceAccountName string,
expirationSeconds int, logger logr.Logger) (*authenticationv1.TokenRequestStatus, error) {

instance := utils.GetAccessInstance()

expiration := int64(expirationSeconds)

treq := &authenticationv1.TokenRequest{}
Expand All @@ -217,7 +236,7 @@ func getServiceAccountTokenRequest(ctx context.Context, serviceAccountNamespace,
}
}

clientset, err := kubernetes.NewForConfig(instance.GetConfig())
clientset, err := kubernetes.NewForConfig(remoteRestConfig)
if err != nil {
return nil, err
}
Expand All @@ -238,7 +257,7 @@ func getServiceAccountTokenRequest(ctx context.Context, serviceAccountNamespace,
}

// getKubeconfigFromToken returns Kubeconfig to access management cluster from token.
func getKubeconfigFromToken(namespace, serviceAccountName, token string) string {
func getKubeconfigFromToken(remoteRestConfig *rest.Config, namespace, serviceAccountName, token string) string {
template := `apiVersion: v1
kind: Config
clusters:
Expand All @@ -258,10 +277,8 @@ contexts:
user: %s
current-context: sveltos-context`

instance := utils.GetAccessInstance()

data := fmt.Sprintf(template, instance.GetConfig().Host,
base64.StdEncoding.EncodeToString(instance.GetConfig().CAData), serviceAccountName, token, namespace, serviceAccountName)
data := fmt.Sprintf(template, remoteRestConfig.Host,
base64.StdEncoding.EncodeToString(remoteRestConfig.CAData), serviceAccountName, token, namespace, serviceAccountName)

return data
}
Expand Down Expand Up @@ -347,7 +364,7 @@ or create a new one with the necessary permissions.

create := parsedArgs["--create"].(bool)

_, err = GenerateKubeconfigForServiceAccount(ctx, namespace, serviceAccount, expirationSeconds,
create, true, logger)
_, err = GenerateKubeconfigForServiceAccount(ctx, utils.GetAccessInstance().GetConfig(),
namespace, serviceAccount, expirationSeconds, create, true, logger)
return err
}
10 changes: 5 additions & 5 deletions internal/commands/generate/generate_kubeconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ var _ = Describe("Register Mgmt Cluster", func() {
utils.InitalizeManagementClusterAcces(scheme, nil, nil, c)

ns := randomString()
Expect(generate.CreateNamespace(context.TODO(), ns,
Expect(generate.CreateNamespace(context.TODO(), c, ns,
textlogger.NewLogger(textlogger.NewConfig(textlogger.Verbosity(1))))).To(Succeed())

currentNs := &corev1.Namespace{}
Expand All @@ -53,14 +53,14 @@ var _ = Describe("Register Mgmt Cluster", func() {
c := fake.NewClientBuilder().WithScheme(scheme).Build()
utils.InitalizeManagementClusterAcces(scheme, nil, nil, c)

Expect(generate.CreateClusterRole(context.TODO(), generate.Projectsveltos,
Expect(generate.CreateClusterRole(context.TODO(), c, generate.Projectsveltos,
textlogger.NewLogger(textlogger.NewConfig(textlogger.Verbosity(1))))).To(Succeed())

currentClusterRole := &rbacv1.ClusterRole{}
Expect(c.Get(context.TODO(), types.NamespacedName{Name: generate.Projectsveltos},
currentClusterRole)).To(Succeed())

Expect(generate.CreateClusterRole(context.TODO(), generate.Projectsveltos,
Expect(generate.CreateClusterRole(context.TODO(), c, generate.Projectsveltos,
textlogger.NewLogger(textlogger.NewConfig(textlogger.Verbosity(1))))).To(Succeed())
})

Expand All @@ -72,7 +72,7 @@ var _ = Describe("Register Mgmt Cluster", func() {

saNamespace := randomString()
saName := randomString()
Expect(generate.CreateClusterRoleBinding(context.TODO(), generate.Projectsveltos,
Expect(generate.CreateClusterRoleBinding(context.TODO(), c, generate.Projectsveltos,
generate.Projectsveltos, saNamespace, saName,
textlogger.NewLogger(textlogger.NewConfig(textlogger.Verbosity(1))))).To(Succeed())

Expand All @@ -88,7 +88,7 @@ var _ = Describe("Register Mgmt Cluster", func() {
Expect(currentClusterRoleBinding.Subjects[0].Namespace).To(Equal(saNamespace))
Expect(currentClusterRoleBinding.Subjects[0].Kind).To(Equal("ServiceAccount"))

Expect(generate.CreateClusterRoleBinding(context.TODO(), generate.Projectsveltos,
Expect(generate.CreateClusterRoleBinding(context.TODO(), c, generate.Projectsveltos,
generate.Projectsveltos, saNamespace, saName,
textlogger.NewLogger(textlogger.NewConfig(textlogger.Verbosity(1))))).To(Succeed())
})
Expand Down
11 changes: 10 additions & 1 deletion internal/commands/onboard/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
ctrl "sigs.k8s.io/controller-runtime"

libsveltosv1alpha1 "github.com/projectsveltos/libsveltos/api/v1alpha1"
logs "github.com/projectsveltos/libsveltos/lib/logsettings"
Expand Down Expand Up @@ -265,9 +267,16 @@ func createKubeconfig(ctx context.Context, fleetClusterContext string, logger lo
}
logger.V(logs.LogDebug).Info(fmt.Sprintf("switched to context %s", fleetClusterContext))

var remoteRestConfig *rest.Config
remoteRestConfig, err = ctrl.GetConfig()
if err != nil {
return "", err
}

logger.V(logs.LogDebug).Info("Generate Kubeconfig")
var data string
data, err = generate.GenerateKubeconfigForServiceAccount(ctx, generate.Projectsveltos, generate.Projectsveltos, 0, true, false, logger)
data, err = generate.GenerateKubeconfigForServiceAccount(ctx, remoteRestConfig, generate.Projectsveltos, generate.Projectsveltos,
0, true, false, logger)
if err != nil {
return "", err
}
Expand Down
Loading