mirror of
https://github.com/1Panel-dev/KubePi.git
synced 2025-11-02 11:24:08 +08:00
feat(clusterrole): 用户创建以及集群内角色的绑定
This commit is contained in:
@@ -3,15 +3,18 @@ package kubernetes
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
v1Cluster "github.com/KubeOperator/ekko/internal/model/v1/cluster"
|
||||
"github.com/KubeOperator/ekko/pkg/certificate"
|
||||
v1 "k8s.io/api/authorization/v1"
|
||||
certv1 "k8s.io/api/certificates/v1"
|
||||
rbacV1 "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/version"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
@@ -19,7 +22,8 @@ type Interface interface {
|
||||
Version() (*version.Info, error)
|
||||
Client() (*kubernetes.Clientset, error)
|
||||
HasPermission(attributes v1.ResourceAttributes) (PermissionCheckResult, error)
|
||||
CreateUser(commonName string) ([]byte, error)
|
||||
CreateCommonUser(commonName string) ([]byte, error)
|
||||
CreateDefaultClusterRoles() error
|
||||
}
|
||||
|
||||
type Kubernetes struct {
|
||||
@@ -35,15 +39,86 @@ func NewKubernetes(cluster v1Cluster.Cluster) Interface {
|
||||
return &Kubernetes{Cluster: &cluster}
|
||||
}
|
||||
|
||||
func (k *Kubernetes) CreateUser(commonName string) ([]byte, error) {
|
||||
func (k *Kubernetes) CreateDefaultClusterRoles() error {
|
||||
defaultRoles := []rbacV1.ClusterRole{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "ekko-admin",
|
||||
Annotations: map[string]string{
|
||||
"ekko-i18n": "cluster_administrator",
|
||||
"created-by": "system",
|
||||
"created-at": time.Now().Format("2006-01-02 15:04:05"),
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"manage": "ekko",
|
||||
},
|
||||
},
|
||||
Rules: []rbacV1.PolicyRule{
|
||||
{
|
||||
APIGroups: []string{"*"},
|
||||
Resources: []string{"*"},
|
||||
Verbs: []string{"*"},
|
||||
},
|
||||
{
|
||||
NonResourceURLs: []string{"*"},
|
||||
Verbs: []string{"*"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "ekko-viewer",
|
||||
Annotations: map[string]string{
|
||||
"ekko-i18n": "cluster_viewer",
|
||||
"created-by": "system",
|
||||
"created-at": time.Now().Format("2006-01-02 15:04:05"),
|
||||
},
|
||||
Labels: map[string]string{
|
||||
"manage": "ekko",
|
||||
},
|
||||
},
|
||||
Rules: []rbacV1.PolicyRule{
|
||||
{
|
||||
APIGroups: []string{"*"},
|
||||
Resources: []string{"*"},
|
||||
Verbs: []string{"list", "get"},
|
||||
},
|
||||
{
|
||||
NonResourceURLs: []string{"*"},
|
||||
Verbs: []string{"list", "get"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
client, err := k.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range defaultRoles {
|
||||
_, err := client.RbacV1().ClusterRoles().Get(context.TODO(), defaultRoles[i].Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
if !strings.Contains(strings.ToLower(err.Error()), "not found") {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err = client.RbacV1().ClusterRoles().Create(context.TODO(), &defaultRoles[i], metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k *Kubernetes) CreateCommonUser(commonName string) ([]byte, error) {
|
||||
// 生成用户证书申请
|
||||
cert, err := certificate.CreateClientCertificateRequest(commonName, &k.PrivateKey)
|
||||
cert, err := certificate.CreateClientCertificateRequest(commonName, k.PrivateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
csr := certv1.CertificateSigningRequest{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "user1",
|
||||
Name: fmt.Sprintf("%s-%s", commonName, "ekko"),
|
||||
},
|
||||
Spec: certv1.CertificateSigningRequestSpec{
|
||||
SignerName: "kubernetes.io/kube-apiserver-client",
|
||||
@@ -60,25 +135,40 @@ func (k *Kubernetes) CreateUser(commonName string) ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := client.CertificatesV1().CertificateSigningRequests().Create(context.TODO(), &csr, metav1.CreateOptions{})
|
||||
createResp, err := client.CertificatesV1().CertificateSigningRequests().Create(context.TODO(), &csr, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
csr = *resp
|
||||
// 审批证书
|
||||
csr.Status.Conditions = append(csr.Status.Conditions, certv1.CertificateSigningRequestCondition{
|
||||
Reason: "approve by ekko",
|
||||
createResp.Status.Conditions = append(createResp.Status.Conditions, certv1.CertificateSigningRequestCondition{
|
||||
Reason: "Approved by Ekko",
|
||||
Type: certv1.CertificateApproved,
|
||||
LastUpdateTime: metav1.Now(),
|
||||
Status: "True",
|
||||
})
|
||||
|
||||
resp, err = client.CertificatesV1().CertificateSigningRequests().UpdateApproval(context.TODO(), csr.Name, &csr, metav1.UpdateOptions{})
|
||||
updateResp, err := client.CertificatesV1().CertificateSigningRequests().UpdateApproval(context.TODO(), createResp.Name, createResp, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 读取证书
|
||||
return resp.Status.Certificate, nil
|
||||
|
||||
var data []byte
|
||||
for i := 0; i < 10; i++ {
|
||||
time.Sleep(1 * time.Second)
|
||||
getResp, err := client.CertificatesV1().CertificateSigningRequests().Get(context.TODO(), updateResp.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if getResp.Status.Certificate != nil {
|
||||
data = getResp.Status.Certificate
|
||||
break
|
||||
}
|
||||
}
|
||||
if data == nil {
|
||||
return nil, errors.New("csr approve time out")
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (k *Kubernetes) HasPermission(attributes v1.ResourceAttributes) (PermissionCheckResult, error) {
|
||||
|
||||
Reference in New Issue
Block a user