feat(api): delete resource and change bug

This commit is contained in:
zhangsetsail 2022-07-25 15:00:16 +08:00
parent 5fd1aa73ed
commit ab28097965
14 changed files with 355 additions and 51 deletions

View File

@ -34,6 +34,9 @@ type ClusterInterface interface {
GetNamespaceResource(w http.ResponseWriter, r *http.Request)
ConvertResource(w http.ResponseWriter, r *http.Request)
ResourceImport(w http.ResponseWriter, r *http.Request)
AddResource(w http.ResponseWriter, r *http.Request)
DeleteResource(w http.ResponseWriter, r *http.Request)
UpdateResource(w http.ResponseWriter, r *http.Request)
}
//TenantInterface interface
@ -177,7 +180,6 @@ type ApplicationInterface interface {
Install(w http.ResponseWriter, r *http.Request)
ListServices(w http.ResponseWriter, r *http.Request)
ListHelmAppReleases(w http.ResponseWriter, r *http.Request)
DeleteConfigGroup(w http.ResponseWriter, r *http.Request)
ListConfigGroups(w http.ResponseWriter, r *http.Request)
SyncComponents(w http.ResponseWriter, r *http.Request)

View File

@ -98,6 +98,9 @@ func (v2 *V2) clusterRouter() chi.Router {
r.Get("/resource", controller.GetManager().GetNamespaceResource)
r.Get("/convert-resource", controller.GetManager().ConvertResource)
r.Post("/convert-resource", controller.GetManager().ResourceImport)
r.Post("/k8s-resource", controller.GetManager().AddResource)
r.Delete("/k8s-resource", controller.GetManager().DeleteResource)
r.Put("/k8s-resource", controller.GetManager().UpdateResource)
return r
}

View File

@ -164,3 +164,59 @@ func (t *ClusterController) ResourceImport(w http.ResponseWriter, r *http.Reques
}
httputil.ReturnSuccess(r, w, rri)
}
func (t *ClusterController) AddResource(w http.ResponseWriter, r *http.Request) {
type HandleResource struct {
Namespace string `json:"namespace"`
AppID string `json:"app_id"`
ResourceYaml string `json:"resource_yaml"`
}
var hr HandleResource
if ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &hr, nil); !ok {
return
}
rri, err := handler.GetClusterHandler().AddAppK8SResource(r.Context(), hr.Namespace, hr.AppID, hr.ResourceYaml)
if err != nil {
err.Handle(r, w)
return
}
httputil.ReturnSuccess(r, w, rri)
}
func (t *ClusterController) UpdateResource(w http.ResponseWriter, r *http.Request) {
type HandelResource struct {
Name string `json:"name"`
AppID string `json:"app_id"`
Namespace string `json:"namespace"`
ResourceYaml string `json:"resource_yaml"`
}
var hr HandelResource
if ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &hr, nil); !ok {
return
}
rri, err := handler.GetClusterHandler().UpdateAppK8SResource(r.Context(), hr.Namespace, hr.AppID, hr.Name, hr.ResourceYaml)
if err != nil {
err.Handle(r, w)
return
}
httputil.ReturnSuccess(r, w, rri)
}
func (t *ClusterController) DeleteResource(w http.ResponseWriter, r *http.Request) {
type HandleResource struct {
Namespace string `json:"namespace"`
AppID string `json:"app_id"`
ResourceYaml string `json:"resource_yaml"`
Name string `json:"name"`
}
var hr HandleResource
if ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &hr, nil); !ok {
return
}
err := handler.GetClusterHandler().DeleteAppK8SResource(r.Context(), hr.Namespace, hr.AppID, hr.Name, hr.ResourceYaml)
if err != nil {
err.Handle(r, w)
return
}
httputil.ReturnSuccess(r, w, nil)
}

View File

@ -5,6 +5,7 @@ import (
"fmt"
"github.com/goodrain/rainbond/api/model"
"github.com/goodrain/rainbond/api/util"
dbmodel "github.com/goodrain/rainbond/db/model"
"github.com/goodrain/rainbond/util/constants"
"github.com/shirou/gopsutil/disk"
"github.com/sirupsen/logrus"
@ -13,6 +14,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"os"
"runtime"
"strconv"
@ -32,13 +34,17 @@ type ClusterHandler interface {
GetNamespaceSource(ctx context.Context, content string, namespace string) (map[string]model.LabelResource, *util.APIHandleError)
ConvertResource(ctx context.Context, namespace string, lr map[string]model.LabelResource) (map[string]model.ApplicationResource, *util.APIHandleError)
ResourceImport(ctx context.Context, namespace string, as map[string]model.ApplicationResource, eid string) (*model.ReturnResourceImport, *util.APIHandleError)
AddAppK8SResource(ctx context.Context, namespace string, appID string, resourceYaml string) ([]*dbmodel.K8sResource, *util.APIHandleError)
DeleteAppK8SResource(ctx context.Context, namespace string, appID string, name string, yaml string) *util.APIHandleError
UpdateAppK8SResource(ctx context.Context, namespace string, appID string, name string, resourceYaml string) (dbmodel.K8sResource, *util.APIHandleError)
}
// NewClusterHandler -
func NewClusterHandler(clientset *kubernetes.Clientset, RbdNamespace string) ClusterHandler {
func NewClusterHandler(clientset *kubernetes.Clientset, RbdNamespace string, config *rest.Config) ClusterHandler {
return &clusterAction{
namespace: RbdNamespace,
clientset: clientset,
config: config,
}
}
@ -47,6 +53,7 @@ type clusterAction struct {
clientset *kubernetes.Clientset
clusterInfoCache *model.ClusterResource
cacheTime time.Time
config *rest.Config
}
func (c *clusterAction) GetClusterInfo(ctx context.Context) (*model.ClusterResource, error) {

View File

@ -147,11 +147,15 @@ func (c *clusterAction) workloadDeployments(ctx context.Context, dmNames []strin
p := volumeMount.MountPath
for _, item := range volume.ConfigMap.Items {
p := path.Join(p, item.Path)
var mode int32
if item.Mode != nil {
mode = *item.Mode
}
configs = append(configs, model.ConfigManagement{
ConfigName: item.Key,
ConfigPath: p,
ConfigValue: cmData[item.Key],
Mode: *item.Mode,
Mode: mode,
})
}
} else {
@ -300,7 +304,7 @@ func (c *clusterAction) workloadDeployments(ctx context.Context, dmNames []strin
hcm.Status = 1
hcm.DetectionMethod = strings.ToLower(string(readinessProbe.HTTPGet.Scheme))
hcm.Mode = "readiness"
hcm.Port = int(livenessProbe.HTTPGet.Port.IntVal)
hcm.Port = int(readinessProbe.HTTPGet.Port.IntVal)
hcm.Path = readinessProbe.HTTPGet.Path
if readinessProbe.Exec != nil {
hcm.Command = strings.Join(readinessProbe.Exec.Command, " ")
@ -314,7 +318,19 @@ func (c *clusterAction) workloadDeployments(ctx context.Context, dmNames []strin
}
}
var attributes []*dbmodel.ComponentK8sAttributes
if resources.Spec.Template.Spec.Containers[0].Env != nil {
envYaml, err := ObjectToJSONORYaml("yaml", resources.Spec.Template.Spec.Containers[0].Env)
if err != nil {
logrus.Errorf("deployment:%v env %v", dmName, err)
return nil
}
envAttributes := &dbmodel.ComponentK8sAttributes{
Name: dbmodel.K8sAttributeNameENV,
SaveType: "yaml",
AttributeValue: envYaml,
}
attributes = append(attributes, envAttributes)
}
if resources.Spec.Template.Spec.Volumes != nil {
volumesYaml, err := ObjectToJSONORYaml("yaml", resources.Spec.Template.Spec.Volumes)
if err != nil {
@ -363,6 +379,7 @@ func (c *clusterAction) workloadDeployments(ctx context.Context, dmNames []strin
}
attributes = append(attributes, labelsAttributes)
}
if resources.Spec.Template.Spec.NodeSelector != nil {
NodeSelectorJSON, err := ObjectToJSONORYaml("json", resources.Spec.Template.Spec.NodeSelector)
if err != nil {
@ -439,7 +456,6 @@ func (c *clusterAction) workloadCronJobs(ctx context.Context, cjNames []string,
}
func (c *clusterAction) getAppKubernetesResources(ctx context.Context, others model.OtherResource, namespace string) []dbmodel.K8sResource {
logrus.Infof("getAppKubernetesResources is begin")
var k8sResources []dbmodel.K8sResource
servicesMap := make(map[string]corev1.Service)
servicesList, err := c.clientset.CoreV1().Services(namespace).List(context.Background(), metav1.ListOptions{})
@ -486,8 +502,9 @@ func (c *clusterAction) getAppKubernetesResources(ctx context.Context, others mo
}
k8sResources = append(k8sResources, dbmodel.K8sResource{
Name: pvc.Name,
Kind: pvcList.Kind,
Kind: model.PVC,
Content: kubernetesResourcesYAML,
Status: "创建成功",
})
}
}
@ -511,8 +528,9 @@ func (c *clusterAction) getAppKubernetesResources(ctx context.Context, others mo
}
k8sResources = append(k8sResources, dbmodel.K8sResource{
Name: ingresses.Name,
Kind: ingressList.Kind,
Kind: model.Ingress,
Content: kubernetesResourcesYAML,
Status: "创建成功",
})
}
}
@ -535,8 +553,9 @@ func (c *clusterAction) getAppKubernetesResources(ctx context.Context, others mo
}
k8sResources = append(k8sResources, dbmodel.K8sResource{
Name: networkPolicies.Name,
Kind: networkPoliciesList.Kind,
Kind: model.NetworkPolicie,
Content: kubernetesResourcesYAML,
Status: "创建成功",
})
}
}
@ -559,8 +578,9 @@ func (c *clusterAction) getAppKubernetesResources(ctx context.Context, others mo
}
k8sResources = append(k8sResources, dbmodel.K8sResource{
Name: configMaps.Name,
Kind: cmList.Kind,
Kind: model.ConfigMap,
Content: kubernetesResourcesYAML,
Status: "创建成功",
})
}
}
@ -583,8 +603,9 @@ func (c *clusterAction) getAppKubernetesResources(ctx context.Context, others mo
}
k8sResources = append(k8sResources, dbmodel.K8sResource{
Name: secrets.Name,
Kind: secretsList.Kind,
Kind: model.Secret,
Content: kubernetesResourcesYAML,
Status: "创建成功",
})
}
}
@ -608,8 +629,9 @@ func (c *clusterAction) getAppKubernetesResources(ctx context.Context, others mo
}
k8sResources = append(k8sResources, dbmodel.K8sResource{
Name: serviceAccounts.Name,
Kind: serviceAccountsList.Kind,
Kind: model.ServiceAccount,
Content: kubernetesResourcesYAML,
Status: "创建成功",
})
}
}
@ -632,8 +654,9 @@ func (c *clusterAction) getAppKubernetesResources(ctx context.Context, others mo
}
k8sResources = append(k8sResources, dbmodel.K8sResource{
Name: roleBindings.Name,
Kind: roleBindingsList.Kind,
Kind: model.RoleBinding,
Content: kubernetesResourcesYAML,
Status: "创建成功",
})
}
}
@ -657,8 +680,9 @@ func (c *clusterAction) getAppKubernetesResources(ctx context.Context, others mo
}
k8sResources = append(k8sResources, dbmodel.K8sResource{
Name: hpa.Name,
Kind: hpaList.Kind,
Kind: model.HorizontalPodAutoscaler,
Content: kubernetesResourcesYAML,
Status: "创建成功",
})
}
}
@ -680,11 +704,12 @@ func (c *clusterAction) getAppKubernetesResources(ctx context.Context, others mo
}
k8sResources = append(k8sResources, dbmodel.K8sResource{
Name: roles.Name,
Kind: rolesList.Kind,
Kind: model.Role,
Content: kubernetesResourcesYAML,
Status: "创建成功",
Success: 1,
})
}
}
logrus.Infof("getAppKubernetesResources is end")
return k8sResources
}

View File

@ -16,7 +16,7 @@ func (c *clusterAction) GetNamespaceSource(ctx context.Context, content string,
cmsMap := make(map[string][]string)
//存储workloads们的secrets
secretsMap := make(map[string][]string)
deployments, cmMap, secretMap := c.getResourceName(ctx, namespace, content, model.Deployment)
deployments, cmMap, secretMap := c.getResourceName(context.Background(), namespace, content, model.Deployment)
if len(cmsMap) != 0 {
cmsMap = MergeMap(cmMap, cmsMap)
}
@ -269,7 +269,7 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
secretMap := make(map[string][]string)
switch resourcesType {
case model.Deployment:
resources, err := c.clientset.AppsV1().Deployments(namespace).List(ctx, metav1.ListOptions{})
resources, err := c.clientset.AppsV1().Deployments(namespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to get Deployment list:%v", err)
return nil, cmMap, secretMap
@ -279,7 +279,7 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
}
isWorkloads = true
case model.Job:
resources, err := c.clientset.BatchV1().Jobs(namespace).List(ctx, metav1.ListOptions{})
resources, err := c.clientset.BatchV1().Jobs(namespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to get Job list:%v", err)
return nil, cmMap, secretMap
@ -289,7 +289,7 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
}
isWorkloads = true
case model.CronJob:
resources, err := c.clientset.BatchV1beta1().CronJobs(namespace).List(ctx, metav1.ListOptions{})
resources, err := c.clientset.BatchV1beta1().CronJobs(namespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to get CronJob list:%v", err)
return nil, cmMap, secretMap
@ -299,7 +299,7 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
}
isWorkloads = true
case model.StateFulSet:
resources, err := c.clientset.AppsV1().StatefulSets(namespace).List(ctx, metav1.ListOptions{})
resources, err := c.clientset.AppsV1().StatefulSets(namespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to get StateFulSets list:%v", err)
return nil, cmMap, secretMap
@ -309,7 +309,7 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
}
isWorkloads = true
case model.Service:
resources, err := c.clientset.CoreV1().Services(namespace).List(ctx, metav1.ListOptions{})
resources, err := c.clientset.CoreV1().Services(namespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to get Services list:%v", err)
return nil, cmMap, secretMap
@ -318,7 +318,7 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
tempResources = append(tempResources, &Resource{ObjectMeta: dm.ObjectMeta})
}
case model.PVC:
resources, err := c.clientset.CoreV1().PersistentVolumeClaims(namespace).List(ctx, metav1.ListOptions{})
resources, err := c.clientset.CoreV1().PersistentVolumeClaims(namespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to get PersistentVolumeClaims list:%v", err)
return nil, cmMap, secretMap
@ -328,7 +328,7 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
tempResources = append(tempResources, &Resource{ObjectMeta: dm.ObjectMeta})
}
case model.Ingress:
resources, err := c.clientset.NetworkingV1().Ingresses(namespace).List(ctx, metav1.ListOptions{})
resources, err := c.clientset.NetworkingV1().Ingresses(namespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to get Ingresses list:%v", err)
return nil, cmMap, secretMap
@ -337,7 +337,7 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
tempResources = append(tempResources, &Resource{ObjectMeta: dm.ObjectMeta})
}
case model.NetworkPolicie:
resources, err := c.clientset.NetworkingV1().NetworkPolicies(namespace).List(ctx, metav1.ListOptions{})
resources, err := c.clientset.NetworkingV1().NetworkPolicies(namespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to get NetworkPolicies list:%v", err)
return nil, cmMap, secretMap
@ -346,7 +346,7 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
tempResources = append(tempResources, &Resource{ObjectMeta: dm.ObjectMeta})
}
case model.ConfigMap:
resources, err := c.clientset.CoreV1().ConfigMaps(namespace).List(ctx, metav1.ListOptions{})
resources, err := c.clientset.CoreV1().ConfigMaps(namespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to get ConfigMaps list:%v", err)
return nil, cmMap, secretMap
@ -355,7 +355,7 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
tempResources = append(tempResources, &Resource{ObjectMeta: dm.ObjectMeta})
}
case model.Secret:
resources, err := c.clientset.CoreV1().Secrets(namespace).List(ctx, metav1.ListOptions{})
resources, err := c.clientset.CoreV1().Secrets(namespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to get Secrets list:%v", err)
return nil, cmMap, secretMap
@ -364,7 +364,7 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
tempResources = append(tempResources, &Resource{ObjectMeta: dm.ObjectMeta})
}
case model.ServiceAccount:
resources, err := c.clientset.CoreV1().ServiceAccounts(namespace).List(ctx, metav1.ListOptions{})
resources, err := c.clientset.CoreV1().ServiceAccounts(namespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to get ServiceAccounts list:%v", err)
return nil, cmMap, secretMap
@ -373,7 +373,7 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
tempResources = append(tempResources, &Resource{ObjectMeta: dm.ObjectMeta})
}
case model.RoleBinding:
resources, err := c.clientset.RbacV1().RoleBindings(namespace).List(ctx, metav1.ListOptions{})
resources, err := c.clientset.RbacV1().RoleBindings(namespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to get RoleBindings list:%v", err)
return nil, cmMap, secretMap
@ -382,7 +382,7 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
tempResources = append(tempResources, &Resource{ObjectMeta: dm.ObjectMeta})
}
case model.HorizontalPodAutoscaler:
resources, err := c.clientset.AutoscalingV1().HorizontalPodAutoscalers(namespace).List(ctx, metav1.ListOptions{})
resources, err := c.clientset.AutoscalingV1().HorizontalPodAutoscalers(namespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to get HorizontalPodAutoscalers list:%v", err)
return nil, cmMap, secretMap
@ -392,7 +392,7 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
labels := make(map[string]string)
switch hpa.Spec.ScaleTargetRef.Kind {
case model.Deployment:
deploy, err := c.clientset.AppsV1().Deployments(namespace).Get(ctx, hpa.Spec.ScaleTargetRef.Name, metav1.GetOptions{})
deploy, err := c.clientset.AppsV1().Deployments(namespace).Get(context.Background(), hpa.Spec.ScaleTargetRef.Name, metav1.GetOptions{})
if err != nil {
logrus.Errorf("The bound deployment does not exist:%v", err)
}
@ -401,7 +401,7 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
}
labels = deploy.ObjectMeta.Labels
case model.StateFulSet:
ss, err := c.clientset.AppsV1().StatefulSets(namespace).Get(ctx, hpa.Spec.ScaleTargetRef.Name, metav1.GetOptions{})
ss, err := c.clientset.AppsV1().StatefulSets(namespace).Get(context.Background(), hpa.Spec.ScaleTargetRef.Name, metav1.GetOptions{})
if err != nil {
logrus.Errorf("The bound deployment does not exist:%v", err)
}
@ -419,7 +419,7 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
app = labels["app.kubernetes.io/name"]
}
if app == "" {
app = "UnLabel"
app = "unclassified"
}
if _, ok := resourceName[app]; ok {
resourceName[app] = append(resourceName[app], hpa.Name)
@ -429,7 +429,7 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
}
return resourceName, nil, nil
case model.Role:
resources, err := c.clientset.RbacV1().Roles(namespace).List(ctx, metav1.ListOptions{})
resources, err := c.clientset.RbacV1().Roles(namespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to get Roles list:%v", err)
return nil, cmMap, secretMap
@ -437,7 +437,6 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
for _, dm := range resources.Items {
tempResources = append(tempResources, &Resource{ObjectMeta: dm.ObjectMeta})
}
logrus.Infof("roles:%v", tempResources)
}
//这一块是统一处理资源按label划分出来
for _, rs := range tempResources {
@ -449,7 +448,7 @@ func (c *clusterAction) getResourceName(ctx context.Context, namespace string, c
app = rs.ObjectMeta.Labels["app.kubernetes.io/name"]
}
if app == "" {
app = "UnLabel"
app = "unclassified"
}
//如果是Workloads类型的资源需要检查其内部configmap、secret、PVC防止没有这三种资源没有label但是用到了
if isWorkloads {
@ -481,7 +480,7 @@ func (c *clusterAction) replenishLabel(ctx context.Context, resource *Resource,
resourceVolume := resource.Template.Spec.Volumes
for _, volume := range resourceVolume {
if pvc := volume.PersistentVolumeClaim; pvc != nil {
PersistentVolumeClaims, err := c.clientset.CoreV1().PersistentVolumeClaims(namespace).Get(ctx, pvc.ClaimName, metav1.GetOptions{})
PersistentVolumeClaims, err := c.clientset.CoreV1().PersistentVolumeClaims(namespace).Get(context.Background(), pvc.ClaimName, metav1.GetOptions{})
if err != nil {
logrus.Errorf("Failed to get PersistentVolumeClaims %s/%s:%v", namespace, pvc.ClaimName, err)
}
@ -493,14 +492,14 @@ func (c *clusterAction) replenishLabel(ctx context.Context, resource *Resource,
PersistentVolumeClaims.Labels["app"] = app
}
}
_, err = c.clientset.CoreV1().PersistentVolumeClaims(namespace).Update(ctx, PersistentVolumeClaims, metav1.UpdateOptions{})
_, err = c.clientset.CoreV1().PersistentVolumeClaims(namespace).Update(context.Background(), PersistentVolumeClaims, metav1.UpdateOptions{})
if err != nil {
logrus.Errorf("PersistentVolumeClaims label update error:%v", err)
}
continue
}
if cm := volume.ConfigMap; cm != nil {
cm, err := c.clientset.CoreV1().ConfigMaps(namespace).Get(ctx, cm.Name, metav1.GetOptions{})
cm, err := c.clientset.CoreV1().ConfigMaps(namespace).Get(context.Background(), cm.Name, metav1.GetOptions{})
if err != nil {
logrus.Errorf("Failed to get ConfigMap:%v", err)
}
@ -511,7 +510,7 @@ func (c *clusterAction) replenishLabel(ctx context.Context, resource *Resource,
}
}
if secret := volume.Secret; secret != nil {
secret, err := c.clientset.CoreV1().Secrets(namespace).Get(ctx, secret.SecretName, metav1.GetOptions{})
secret, err := c.clientset.CoreV1().Secrets(namespace).Get(context.Background(), secret.SecretName, metav1.GetOptions{})
if err != nil {
logrus.Errorf("Failed to get Scret:%v", err)
}

View File

@ -31,6 +31,7 @@ import (
"github.com/goodrain/rainbond/worker/client"
"github.com/sirupsen/logrus"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
)
@ -42,6 +43,7 @@ func InitHandle(conf option.Config,
kubeClient *kubernetes.Clientset,
rainbondClient versioned.Interface,
k8sClient k8sclient.Client,
config *rest.Config,
) error {
mq := api_db.MQManager{
EtcdClientArgs: etcdClientArgs,
@ -80,7 +82,7 @@ func InitHandle(conf option.Config,
batchOperationHandler = CreateBatchOperationHandler(mqClient, statusCli, operationHandler)
defaultAppRestoreHandler = NewAppRestoreHandler()
defPodHandler = NewPodHandler(statusCli)
defClusterHandler = NewClusterHandler(kubeClient, conf.RbdNamespace)
defClusterHandler = NewClusterHandler(kubeClient, conf.RbdNamespace, config)
defaultVolumeTypeHandler = CreateVolumeTypeManger(statusCli)
defaultEtcdHandler = NewEtcdHandler(etcdcli)
defaultmonitorHandler = NewMonitorHandler(prometheusCli)

196
api/handler/resource.go Normal file
View File

@ -0,0 +1,196 @@
package handler
import (
"bytes"
"context"
"fmt"
"github.com/goodrain/rainbond/api/util"
"github.com/goodrain/rainbond/db"
dbmodel "github.com/goodrain/rainbond/db/model"
"github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer/yaml"
yamlt "k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/restmapper"
)
func (c *clusterAction) AddAppK8SResource(ctx context.Context, namespace string, appID string, resourceYaml string) ([]*dbmodel.K8sResource, *util.APIHandleError) {
logrus.Info("begin AddAppK8SResource")
resourceObjects, err := c.HandleResourceYaml(resourceYaml, namespace, "create", "")
if err != nil {
return nil, &util.APIHandleError{Code: 400, Err: fmt.Errorf("failed to parse yaml into k8s resource:%v", err)}
}
var resourceList []*dbmodel.K8sResource
for _, resourceObject := range resourceObjects {
resource := resourceObject
resourceYaml, err := ObjectToJSONORYaml("yaml", resource.Resource)
if err != nil {
resourceList = append(resourceList, &dbmodel.K8sResource{
AppID: appID,
Name: resource.Resource.GetName(),
Kind: resource.Resource.GetKind(),
Content: resourceYaml,
Status: resource.Status,
Success: resource.Success,
})
}
resourceList = append(resourceList, &dbmodel.K8sResource{
AppID: appID,
Name: resource.Resource.GetName(),
Kind: resource.Resource.GetKind(),
Content: resourceYaml,
Status: resource.Status,
Success: resource.Success,
})
}
err = db.GetManager().K8sResourceDao().CreateK8sResourceInBatch(resourceList)
if err != nil {
return nil, &util.APIHandleError{Code: 400, Err: fmt.Errorf("CreateK8sResource %v", err)}
}
return resourceList, nil
}
func (c *clusterAction) UpdateAppK8SResource(ctx context.Context, namespace string, appID string, name string, resourceYaml string) (dbmodel.K8sResource, *util.APIHandleError) {
//resourceObjects, err := c.HandleResourceYaml(resourceYaml, namespace, "update", name)
//if err != nil {
// return nil, &util.APIHandleError{Code: 400, Err: fmt.Errorf("failed to parse yaml into k8s resource:%v", err)}
//}
//var resourceList []*dbmodel.K8sResource
//
//err = db.GetManager().K8sResourceDao().CreateK8sResourceInBatch(resourceList)
//if err != nil {
// return nil, &util.APIHandleError{Code: 400, Err: fmt.Errorf("CreateK8sResource %v", err)}
//}
//return resourceList, nil
return dbmodel.K8sResource{}, nil
}
func (c *clusterAction) DeleteAppK8SResource(ctx context.Context, namespace string, appID string, name string, resourceYaml string) *util.APIHandleError {
logrus.Info("begin DeleteAppK8SResource")
_, err := c.HandleResourceYaml(resourceYaml, namespace, "delete", name)
if err != nil {
return &util.APIHandleError{Code: 400, Err: fmt.Errorf("DeleteAppK8SResource %v", err)}
}
err = db.GetManager().K8sResourceDao().DeleteK8sResourceInBatch(appID, name)
if err != nil {
return &util.APIHandleError{Code: 400, Err: fmt.Errorf("DeleteAppK8SResource %v", err)}
}
return nil
}
type BuildResource struct {
Resource *unstructured.Unstructured
Success int
Status string
}
func (c *clusterAction) HandleResourceYaml(resourceYaml string, namespace string, change string, name string) ([]BuildResource, error) {
var buildResourceList []BuildResource
dc, err := dynamic.NewForConfig(c.config)
if err != nil {
logrus.Errorf("%v", err)
return nil, err
}
resourceYamlByte := []byte(resourceYaml)
if err != nil {
logrus.Errorf("%v", err)
return nil, err
}
decoder := yamlt.NewYAMLOrJSONDecoder(bytes.NewReader(resourceYamlByte), 100)
for {
var rawObj runtime.RawExtension
if err = decoder.Decode(&rawObj); err != nil {
break
}
var status string
var success int
if change == "create" {
status = "创建失败"
success = 3
} else {
status = "更新失败"
success = 4
}
obj, gvk, err := yaml.NewDecodingSerializer(unstructured.UnstructuredJSONScheme).Decode(rawObj.Raw, nil, nil)
unstructuredMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
if err != nil {
logrus.Errorf("%v", err)
buildResourceList = append(buildResourceList, BuildResource{
Resource: nil,
Success: success,
Status: fmt.Sprintf("%v%v", status, err),
})
continue
}
unstructuredObj := &unstructured.Unstructured{Object: unstructuredMap}
gr, err := restmapper.GetAPIGroupResources(c.clientset.Discovery())
if err != nil {
logrus.Errorf("%v", err)
buildResourceList = append(buildResourceList, BuildResource{
Resource: nil,
Success: success,
Status: fmt.Sprintf("%v%v", status, err),
})
continue
}
mapper := restmapper.NewDiscoveryRESTMapper(gr)
mapping, err := mapper.RESTMapping(gvk.GroupKind(), gvk.Version)
if err != nil {
buildResourceList = append(buildResourceList, BuildResource{
Resource: nil,
Success: success,
Status: fmt.Sprintf("%v%v", status, err),
})
continue
}
var dri dynamic.ResourceInterface
if mapping.Scope.Name() == meta.RESTScopeNameNamespace {
unstructuredObj.SetNamespace(namespace)
dri = dc.Resource(mapping.Resource).Namespace(unstructuredObj.GetNamespace())
} else {
dri = dc.Resource(mapping.Resource)
}
switch change {
case "create":
obj, err := dri.Create(context.TODO(), unstructuredObj, metav1.CreateOptions{})
var br BuildResource
if err != nil {
br = BuildResource{
Resource: obj,
Success: success,
Status: fmt.Sprintf("%v%v", status, err),
}
} else {
br = BuildResource{
Resource: obj,
Success: 1,
Status: fmt.Sprintf("创建成功"),
}
}
buildResourceList = append(buildResourceList, br)
case "delete":
err := dri.Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
logrus.Errorf("delete k8s resource error%v", err)
}
case "update":
//obj, err := dri.Update(context.TODO(), unstructuredObj, metav1.UpdateOptions{})
//if err != nil {
// r := []BuildResource{{
// obj,
// fmt.Sprintf("创建失败%v", err),
// }}
//} else {
//
//}
//
//return r, nil
}
}
return buildResourceList, nil
}

View File

@ -24,7 +24,7 @@ func (c *clusterAction) ResourceImport(ctx context.Context, namespace string, as
logrus.Infof("ResourceImport function begin")
var returnResourceImport model.ReturnResourceImport
err := db.GetManager().DB().Transaction(func(tx *gorm.DB) error {
tenant, err := c.createTenant(ctx, eid, namespace, tx)
tenant, err := c.createTenant(context.Background(), eid, namespace, tx)
returnResourceImport.Tenant = tenant
if err != nil {
logrus.Errorf("%v", err)
@ -43,7 +43,7 @@ func (c *clusterAction) ResourceImport(ctx context.Context, namespace string, as
}
var ca []model.ComponentAttributes
for _, componentResource := range components.ConvertResource {
component, err := c.createComponent(ctx, app, tenant.UUID, componentResource, namespace)
component, err := c.createComponent(context.Background(), app, tenant.UUID, componentResource, namespace)
if err != nil {
logrus.Errorf("%v", err)
return &util.APIHandleError{Code: 400, Err: fmt.Errorf("create app error:%v", err)}
@ -104,12 +104,15 @@ func (c *clusterAction) createTenant(ctx context.Context, eid string, namespace
return nil, err
}
}
ns, err := c.clientset.CoreV1().Namespaces().Get(ctx, namespace, metav1.GetOptions{})
ns, err := c.clientset.CoreV1().Namespaces().Get(context.Background(), namespace, metav1.GetOptions{})
if err != nil {
return nil, &util.APIHandleError{Code: 404, Err: fmt.Errorf("failed to get namespace %v:%v", namespace, err)}
}
if ns.Labels == nil {
ns.Labels = make(map[string]string)
}
ns.Labels[constants.ResourceManagedByLabel] = constants.Rainbond
_, err = c.clientset.CoreV1().Namespaces().Update(ctx, ns, metav1.UpdateOptions{})
_, err = c.clientset.CoreV1().Namespaces().Update(context.Background(), ns, metav1.UpdateOptions{})
if err != nil {
return nil, &util.APIHandleError{Code: 404, Err: fmt.Errorf("failed to add label to namespace %v:%v", namespace, err)}
}
@ -184,7 +187,7 @@ func (c *clusterAction) createComponent(ctx context.Context, app *dbmodel.Applic
logrus.Errorf("add service error, %v", err)
return nil, err
}
dm, err := c.clientset.AppsV1().Deployments(namespace).Get(ctx, component.ComponentsName, metav1.GetOptions{})
dm, err := c.clientset.AppsV1().Deployments(namespace).Get(context.Background(), component.ComponentsName, metav1.GetOptions{})
if err != nil {
logrus.Errorf("failed to get %v deployment %v:%v", namespace, component.ComponentsName, err)
return nil, &util.APIHandleError{Code: 404, Err: fmt.Errorf("failed to get deployment %v:%v", namespace, err)}
@ -201,7 +204,7 @@ func (c *clusterAction) createComponent(ctx context.Context, app *dbmodel.Applic
dm.Spec.Template.Labels["version"] = ts.DeployVersion
dm.Spec.Template.Labels["creater_id"] = string(rainbondutil.NewTimeVersion())
dm.Spec.Template.Labels["migrator"] = "rainbond"
_, err = c.clientset.AppsV1().Deployments(namespace).Update(ctx, dm, metav1.UpdateOptions{})
_, err = c.clientset.AppsV1().Deployments(namespace).Update(context.Background(), dm, metav1.UpdateOptions{})
if err != nil {
logrus.Errorf("failed to update deployment %v:%v", namespace, err)
return nil, &util.APIHandleError{Code: 404, Err: fmt.Errorf("failed to update deployment %v:%v", namespace, err)}
@ -348,6 +351,9 @@ func (c *clusterAction) createK8sAttributes(specials []*dbmodel.ComponentK8sAttr
//ObjectToJSONORYaml changeType true is json / yaml
func ObjectToJSONORYaml(changeType string, data interface{}) (string, error) {
if data == nil {
return "", nil
}
dataJSON, err := json.Marshal(data)
if err != nil {
return "", fmt.Errorf("json serialization failed err:%v", err)

View File

@ -23,9 +23,7 @@ import (
"os"
"os/signal"
"syscall"
rainbondscheme "github.com/goodrain/rainbond/pkg/generated/clientset/versioned/scheme"
"github.com/goodrain/rainbond/api/controller"
"github.com/goodrain/rainbond/api/db"
"github.com/goodrain/rainbond/api/discover"
@ -34,6 +32,7 @@ import (
"github.com/goodrain/rainbond/cmd/api/option"
"github.com/goodrain/rainbond/event"
"github.com/goodrain/rainbond/pkg/generated/clientset/versioned"
rainbondscheme "github.com/goodrain/rainbond/pkg/generated/clientset/versioned/scheme"
etcdutil "github.com/goodrain/rainbond/util/etcd"
k8sutil "github.com/goodrain/rainbond/util/k8s"
"github.com/goodrain/rainbond/worker/client"
@ -121,7 +120,7 @@ func Run(s *option.APIServer) error {
//初始化 middleware
handler.InitProxy(s.Config)
//创建handle
if err := handler.InitHandle(s.Config, etcdClientArgs, cli, etcdcli, clientset, rainbondClient, k8sClient); err != nil {
if err := handler.InitHandle(s.Config, etcdClientArgs, cli, etcdcli, clientset, rainbondClient, k8sClient, config); err != nil {
logrus.Errorf("init all handle error, %v", err)
return err
}

View File

@ -636,4 +636,5 @@ type K8sResourceDao interface {
Dao
ListByAppID(appID string) ([]model.K8sResource, error)
CreateK8sResourceInBatch(k8sResources []*model.K8sResource) error
DeleteK8sResourceInBatch(appID, name string) error
}

View File

@ -107,6 +107,8 @@ type K8sResource struct {
Content string `gorm:"column:content;type:longtext" json:"content"`
// resource create status
Status string `gorm:"column:status;type:longtext" json:"status"`
//whether it was created successfully
Success int `gorm:"column:success;type:int" json:"success"`
}
// TableName return tableName "k8s_resources"

View File

@ -35,6 +35,8 @@ const (
K8sAttributeNameAffinity = "affinity"
//K8sAttributeNameVolumeMounts -
K8sAttributeNameVolumeMounts = "volumeMounts"
//K8sAttributeNameENV -
K8sAttributeNameENV = "env"
)
// ComponentK8sAttributes -

View File

@ -59,3 +59,7 @@ func (t *K8sResourceDaoImpl) CreateK8sResourceInBatch(k8sResources []*model.K8sR
}
return nil
}
func (t *K8sResourceDaoImpl) DeleteK8sResourceInBatch(appID, name string) error {
return t.DB.Where("app_id=? and name=?", appID, name).Delete(&model.K8sResource{}).Error
}