package infrastructure import ( "context" "errors" "fmt" "oc-datacenter/conf" authv1 "k8s.io/api/authentication/v1" v1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" ) type KubernetesService struct { Set *kubernetes.Clientset } func NewKubernetesService() (Infrastructure, error) { config := &rest.Config{ Host: conf.GetConfig().KubeHost + ":" + conf.GetConfig().KubePort, TLSClientConfig: rest.TLSClientConfig{ CAData: []byte(conf.GetConfig().KubeCA), CertData: []byte(conf.GetConfig().KubeCert), KeyData: []byte(conf.GetConfig().KubeData), }, } // Create clientset clientset, err := kubernetes.NewForConfig(config) fmt.Println("NewForConfig", clientset, err) if err != nil { return nil, errors.New("Error creating Kubernetes client: " + err.Error()) } if clientset == nil { return nil, errors.New("Error creating Kubernetes client: clientset is nil") } return &KubernetesService{ Set: clientset, }, nil } func (k *KubernetesService) CreateNamespace(ctx context.Context, ns string) error { // Define the namespace namespace := &v1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: ns, }, } // Create the namespace fmt.Println("Creating namespace...", k.Set) if _, err := k.Set.CoreV1().Namespaces().Create(ctx, namespace, metav1.CreateOptions{}); err != nil { return errors.New("Error creating namespace: " + err.Error()) } fmt.Println("Namespace created successfully!") return nil } func (k *KubernetesService) CreateServiceAccount(ctx context.Context, ns string) error { // Create the ServiceAccount object serviceAccount := &v1.ServiceAccount{ ObjectMeta: metav1.ObjectMeta{ Name: "sa-" + ns, Namespace: ns, }, } // Create the ServiceAccount in the specified namespace _, err := k.Set.CoreV1().ServiceAccounts(ns).Create(ctx, serviceAccount, metav1.CreateOptions{}) if err != nil { return errors.New("Failed to create ServiceAccount: " + err.Error()) } return nil } func (k *KubernetesService) CreateRole(ctx context.Context, ns string, role string, groups [][]string, resources [][]string, verbs [][]string) error { // Create the Role object if len(groups) != len(resources) || len(resources) != len(verbs) { return errors.New("Invalid input: groups, resources, and verbs must have the same length") } rules := []rbacv1.PolicyRule{} for i, group := range groups { rules = append(rules, rbacv1.PolicyRule{ APIGroups: group, Resources: resources[i], Verbs: verbs[i], }) } r := &rbacv1.Role{ ObjectMeta: metav1.ObjectMeta{ Name: role, Namespace: ns, }, Rules: rules, } // Create the Role in the specified namespace _, err := k.Set.RbacV1().Roles(ns).Create(ctx, r, metav1.CreateOptions{}) if err != nil { return errors.New("Failed to create Role: " + err.Error()) } return nil } func (k *KubernetesService) CreateRoleBinding(ctx context.Context, ns string, roleBinding string, role string) error { // Create the RoleBinding object rb := &rbacv1.RoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: roleBinding, Namespace: ns, }, Subjects: []rbacv1.Subject{ { Kind: "ServiceAccount", Name: "sa-" + ns, Namespace: ns, }, }, RoleRef: rbacv1.RoleRef{ Kind: "Role", Name: role, APIGroup: "rbac.authorization.k8s.io", }, } // Create the RoleBinding in the specified namespace _, err := k.Set.RbacV1().RoleBindings(ns).Create(ctx, rb, metav1.CreateOptions{}) if err != nil { return errors.New("Failed to create RoleBinding: " + err.Error()) } return nil } func (k *KubernetesService) DeleteNamespace(ctx context.Context, ns string) error { // Delete the namespace if err := k.Set.CoreV1().Namespaces().Delete(ctx, ns, metav1.DeleteOptions{}); err != nil { return errors.New("Error deleting namespace: " + err.Error()) } fmt.Println("Namespace deleted successfully!") return nil } func (k *KubernetesService) GetToken(ctx context.Context, ns string, duration int) (string, error) { // Define TokenRequest (valid for 1 hour) d := int64(duration) tokenRequest := &authv1.TokenRequest{ Spec: authv1.TokenRequestSpec{ ExpirationSeconds: &d, // 1 hour validity }, } // Generate the token token, err := k.Set.CoreV1(). ServiceAccounts(ns). CreateToken(ctx, "sa-"+ns, tokenRequest, metav1.CreateOptions{}) if err != nil { return "", errors.New("Failed to create token for ServiceAccount: " + err.Error()) } return token.Status.Token, nil }