Add controller to create Ceph secret

This commit is contained in:
wileywang
2018-09-17 14:40:40 +08:00
parent 5b52580b37
commit 13b4b0eb04
16 changed files with 11385 additions and 4 deletions

View File

@@ -34,6 +34,11 @@ import (
"k8s.io/client-go/informers"
"k8s.io/kubernetes/pkg/apis/core"
"strconv"
"strings"
"kubesphere.io/kubesphere/pkg/client"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/options"
@@ -226,6 +231,76 @@ func (ctl *NamespaceCtl) createRoleAndRuntime(item v1.Namespace) {
}
}
func (ctl *NamespaceCtl) createCephSecretAfterNewNs(item v1.Namespace) {
// Kubernetes version must <= 1.10
openInfo, err := ctl.K8sClient.OpenAPISchema()
if err != nil {
glog.Error("consult openAPI error: ", err)
return
}
if openInfo == nil {
glog.Error("cannot find openAPI info")
return
}
ver := strings.Split(openInfo.GetInfo().GetVersion(), ".")
midVer, _ := strconv.Atoi(ver[1])
if !(ver[0] == "v1" && midVer < 11) {
glog.Infof("disable Ceph secret controller due to Kubernetes version %s mismatch",
openInfo.GetInfo().GetVersion())
return
}
// Create Ceph secret in the new namespace
newNsName := item.Name
scList, _ := ctl.K8sClient.StorageV1().StorageClasses().List(metaV1.ListOptions{})
if scList == nil {
return
}
for _, sc := range scList.Items {
if sc.Provisioner == rbdPluginName {
glog.Infof("would create Ceph user secret in storage class %s at namespace %s", sc.GetName(), newNsName)
if secretName, ok := sc.Parameters[rbdUserSecretNameKey]; ok {
secret, err := ctl.K8sClient.CoreV1().Secrets(core.NamespaceSystem).Get(secretName, metaV1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
glog.Errorf("cannot find secret in namespace %s, error: %s", core.NamespaceSystem, err.Error())
continue
}
glog.Errorf("failed to find secret in namespace %s, error: %s", core.NamespaceSystem, err.Error())
continue
}
glog.Infof("succeed to find secret %s in namespace %s", secret.GetName(), secret.GetNamespace())
newSecret := &v1.Secret{
TypeMeta: metaV1.TypeMeta{
Kind: secret.Kind,
APIVersion: secret.APIVersion,
},
ObjectMeta: metaV1.ObjectMeta{
Name: secret.GetName(),
Namespace: newNsName,
Labels: secret.GetLabels(),
Annotations: secret.GetAnnotations(),
DeletionGracePeriodSeconds: secret.GetDeletionGracePeriodSeconds(),
ClusterName: secret.GetClusterName(),
},
Data: secret.Data,
StringData: secret.StringData,
Type: secret.Type,
}
glog.Infof("creating secret %s in namespace %s...", newSecret.GetName(), newSecret.GetNamespace())
_, err = ctl.K8sClient.CoreV1().Secrets(newSecret.GetNamespace()).Create(newSecret)
if err != nil {
glog.Errorf("failed to create secret in namespace %s, error: %v", newSecret.GetNamespace(), err)
continue
}
} else {
glog.Errorf("failed to find user secret name in storage class %s", sc.GetName())
}
}
}
}
func (ctl *NamespaceCtl) generateObject(item v1.Namespace) *Namespace {
var displayName string
@@ -305,6 +380,7 @@ func (ctl *NamespaceCtl) initListerAndInformer() {
mysqlObject := ctl.generateObject(*object)
db.Create(mysqlObject)
ctl.createRoleAndRuntime(*object)
ctl.createCephSecretAfterNewNs(*object)
},
UpdateFunc: func(old, new interface{}) {
object := new.(*v1.Namespace)

View File

@@ -20,12 +20,23 @@ import (
"fmt"
"time"
"github.com/golang/glog"
"k8s.io/api/storage/v1"
"strconv"
"strings"
"github.com/golang/glog"
coreV1 "k8s.io/api/core/v1"
"k8s.io/api/storage/v1"
"k8s.io/apimachinery/pkg/api/errors"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/informers"
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/apis/core"
)
const (
rbdPluginName = "kubernetes.io/rbd"
rbdUserSecretNameKey = "userSecretName"
)
func (ctl *StorageClassCtl) generateObject(item v1.StorageClass) *StorageClass {
@@ -95,6 +106,102 @@ func (ctl *StorageClassCtl) total() int {
return len(list)
}
func (ctl *StorageClassCtl) createCephSecretAfterNewSc(item v1.StorageClass) {
// Kubernetes version must <= 1.10
openInfo, err := ctl.K8sClient.OpenAPISchema()
if err != nil {
glog.Error("consult openAPI error: ", err)
return
}
if openInfo == nil {
glog.Error("cannot find openAPI info")
return
}
ver := strings.Split(openInfo.GetInfo().GetVersion(), ".")
midVer, _ := strconv.Atoi(ver[1])
if !(ver[0] == "v1" && midVer < 11) {
glog.Infof("disable Ceph secret controller due to Kubernetes version %s mismatch",
openInfo.GetInfo().GetVersion())
return
}
// Find Ceph secret in the new storage class
if item.Provisioner != rbdPluginName {
return
}
var secret *coreV1.Secret
if secretName, ok := item.Parameters[rbdUserSecretNameKey]; ok {
secret, err = ctl.K8sClient.CoreV1().Secrets(core.NamespaceSystem).Get(secretName, metaV1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
glog.Errorf("cannot find secret %s in namespace %s", secretName, core.NamespaceSystem)
return
}
glog.Error("failed to find secret, error: ", err)
return
}
glog.Infof("succeed to find secret %s in namespace %s", secret.GetName(), secret.GetNamespace())
} else {
glog.Errorf("failed to find user secret name in storage class %s", item.GetName())
return
}
// Create or update Ceph secret in each namespace
nsList, err := ctl.K8sClient.CoreV1().Namespaces().List(metaV1.ListOptions{})
if err != nil {
glog.Error("failed to list namespace, error: ", err)
return
}
for _, ns := range nsList.Items {
if ns.GetName() == core.NamespaceSystem {
glog.Infof("skip creating Ceph secret in namespace %s", core.NamespaceSystem)
continue
}
newSecret := &coreV1.Secret{
TypeMeta: metaV1.TypeMeta{
Kind: secret.Kind,
APIVersion: secret.APIVersion,
},
ObjectMeta: metaV1.ObjectMeta{
Name: secret.GetName(),
Namespace: ns.GetName(),
Labels: secret.GetLabels(),
Annotations: secret.GetAnnotations(),
DeletionGracePeriodSeconds: secret.GetDeletionGracePeriodSeconds(),
ClusterName: secret.GetClusterName(),
},
Data: secret.Data,
StringData: secret.StringData,
Type: secret.Type,
}
_, err := ctl.K8sClient.CoreV1().Secrets(newSecret.GetNamespace()).Get(newSecret.GetName(), metaV1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
// Create secret
_, err := ctl.K8sClient.CoreV1().Secrets(newSecret.GetNamespace()).Create(newSecret)
if err != nil {
glog.Errorf("failed to create secret in namespace %s, error: %v", newSecret.GetNamespace(), err)
} else {
glog.Infof("succeed to create secret %s in namespace %s", newSecret.GetName(),
newSecret.GetNamespace())
}
} else {
glog.Errorf("failed to find secret in namespace %s, error: %v", newSecret.GetNamespace(), err)
}
} else {
// Update secret
_, err = ctl.K8sClient.CoreV1().Secrets(newSecret.GetNamespace()).Update(newSecret)
if err != nil {
glog.Errorf("failed to update secret in namespace %s, error: %v", newSecret.GetNamespace(), err)
continue
} else {
glog.Infof("succeed to update secret %s in namespace %s", newSecret.GetName(), newSecret.GetNamespace())
}
}
}
}
func (ctl *StorageClassCtl) initListerAndInformer() {
db := ctl.DB
@@ -108,6 +215,7 @@ func (ctl *StorageClassCtl) initListerAndInformer() {
object := obj.(*v1.StorageClass)
mysqlObject := ctl.generateObject(*object)
db.Create(mysqlObject)
ctl.createCephSecretAfterNewSc(*object)
},
UpdateFunc: func(old, new interface{}) {
object := new.(*v1.StorageClass)