Added routes and methods to create admiralty resources : secrets, target sources
This commit is contained in:
		| @@ -1,12 +1,25 @@ | ||||
| package controllers | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"oc-datacenter/infrastructure" | ||||
| 	"slices" | ||||
|  | ||||
| 	beego "github.com/beego/beego/v2/server/web" | ||||
| ) | ||||
|  | ||||
| type KubeInfo struct { | ||||
| 	Url 			*string | ||||
| 	KubeCA   		*string | ||||
| 	KubeCert 		*string | ||||
| 	KubeKey 		*string | ||||
| } | ||||
|  | ||||
| type Kubeconfig struct { | ||||
| 	Data	*string | ||||
| } | ||||
|  | ||||
| // Operations about the admiralty objects of the datacenter | ||||
| type AdmiraltyController struct { | ||||
| 	beego.Controller | ||||
| @@ -57,4 +70,215 @@ func (c *AdmiraltyController) GetOneTarget() { | ||||
|  | ||||
| 	c.Data["json"] = id | ||||
| 	c.ServeJSON() | ||||
| } | ||||
|  | ||||
| // @Title CreateSource | ||||
| // @Description Create an Admiralty Source on remote cluster | ||||
| // @Param dc_id 	path	string 		true 	"which dc to contact" | ||||
| // @Param execution path 	string 		true	"execution id of the workflow" | ||||
| // @Param serviceAccount	body 	controllers.KubeInfo	true	"url and serviceAccount to use with the source formatted as json object" | ||||
| // @Success 200  | ||||
| // @router /sources/:dc_id/:execution [post] | ||||
| func (c *AdmiraltyController) CreateSource() { | ||||
| 	var data KubeInfo | ||||
| 	json.Unmarshal(c.Ctx.Input.CopyBody(10000000),&data) | ||||
| 	if data.Url == nil || data.KubeCA == nil || data.KubeCert == nil|| data.KubeKey == nil { | ||||
| 		c.Ctx.Output.SetStatus(500) | ||||
| 		c.ServeJSON() | ||||
| 		missingData := fmt.Sprint(data) | ||||
| 		c.Data["json"] = map[string]string{"error" : "Missing something in " + missingData} | ||||
| 		c.ServeJSON() | ||||
| 	} | ||||
| 	fmt.Println("") | ||||
| 	fmt.Println("URL : %v", data.Url) | ||||
| 	fmt.Println("") | ||||
| 	fmt.Println("CA : %v", data.KubeCA) | ||||
| 	fmt.Println("") | ||||
| 	fmt.Println("Key : ", data.KubeKey) | ||||
|  | ||||
| 	dc_id := c.Ctx.Input.Param(":dc_id") | ||||
| 	execution := c.Ctx.Input.Param(":execution") | ||||
| 	_ = dc_id | ||||
| 	serv, err := infrastructure.NewRemoteKubernetesService( | ||||
| 		*data.Url, | ||||
| 		*data.KubeCA, | ||||
| 		*data.KubeCert, | ||||
| 		*data.KubeKey, | ||||
| 	)  | ||||
| 	if err != nil { | ||||
| 		// change code to 500 | ||||
| 		c.Ctx.Output.SetStatus(500) | ||||
| 		c.ServeJSON() | ||||
| 		c.Data["json"] = map[string]string{"error": err.Error()} | ||||
| 		c.ServeJSON() | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	res, err := serv.CreateAdmiraltySource(execution) | ||||
| 	if err != nil { | ||||
| 		// change code to 500 | ||||
| 		c.Ctx.Output.SetStatus(500) | ||||
| 		c.Data["json"] = map[string]string{"error": err.Error()} | ||||
| 		c.ServeJSON() | ||||
| 		return | ||||
| 	} | ||||
| 	 | ||||
| 	// TODO : Return a description of the created resource | ||||
| 	var respData map[string]interface{} | ||||
| 	err = json.Unmarshal(res,&respData) | ||||
| 	c.Data["json"] = respData | ||||
| 	c.ServeJSON() | ||||
| 	 | ||||
| } | ||||
|  | ||||
| // @Title CreateAdmiraltyTarget | ||||
| // @Description Create an Admiralty Target in the namespace associated to the executionID | ||||
| // @Param dc_id 	path	string 		true 	"which dc to contact" | ||||
| // @Param execution path 	string 		true	"execution id of the workflow" | ||||
| // @Success 201 | ||||
| // @router /target/:dc_id/:execution [post] | ||||
| func (c *AdmiraltyController) CreateAdmiraltyTarget(){ | ||||
| 	var data map[string]interface{} | ||||
| 	dc_id := c.Ctx.Input.Param(":dc_id") | ||||
| 	execution := c.Ctx.Input.Param(":execution") | ||||
| 	_ = dc_id | ||||
|  | ||||
| 	serv, err := infrastructure.NewService() | ||||
| 	if err != nil { | ||||
| 		// change code to 500 | ||||
| 		c.Ctx.Output.SetStatus(500) | ||||
| 		c.Data["json"] = map[string]string{"error": err.Error()} | ||||
| 		c.ServeJSON() | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	resp, err := serv.CreateAdmiraltyTarget(execution) | ||||
| 	if err != nil { | ||||
| 		// change code to 500 | ||||
| 		c.Ctx.Output.SetStatus(500) | ||||
| 		c.Data["json"] = map[string]string{"error": err.Error()} | ||||
| 		c.ServeJSON() | ||||
| 		return | ||||
| 	} | ||||
| 	if resp == nil { | ||||
| 		fmt.Println("Error while trying to create Admiralty target") | ||||
| 		fmt.Println(resp) | ||||
| 		fmt.Println(err) | ||||
| 		c.Ctx.Output.SetStatus(401) | ||||
| 		c.Data["json"] = map[string]string{"error" : "Could not perform the action" } | ||||
| 		c.ServeJSON() | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	err = json.Unmarshal(resp,&data) | ||||
| 	if err != nil { | ||||
| 		// change code to 500 | ||||
| 		c.Ctx.Output.SetStatus(500) | ||||
| 		c.ServeJSON() | ||||
| 		c.Data["json"] = map[string]string{"error": err.Error()} | ||||
| 		return | ||||
| 	} | ||||
| 	c.Data["json"] = data | ||||
| 	c.ServeJSON() | ||||
|  | ||||
| } | ||||
|  | ||||
| // @Title GetKubeSecret | ||||
| // @Description Retrieve the secret created from a Kubeconfig that will be associated to an Admiralty Target | ||||
| // @Param dc_id 	path	string 		true 	"which dc to contact" | ||||
| // @Param execution path 	string 		true	"execution id of the workflow" | ||||
| // @Success 200  | ||||
| // @router /secret/:dc_id/:execution [get] | ||||
| func(c *AdmiraltyController) GetKubeSecret() { | ||||
| 	var data map[string]interface{}  | ||||
| 	dc_id := c.Ctx.Input.Param(":dc_id") | ||||
| 	execution := c.Ctx.Input.Param(":execution") | ||||
| 	_ = dc_id | ||||
|  | ||||
| 	serv, err := infrastructure.NewService() | ||||
| 	if err != nil { | ||||
| 		// change code to 500 | ||||
| 		c.Ctx.Output.SetStatus(500) | ||||
| 		c.Data["json"] = map[string]string{"error": err.Error()} | ||||
| 		c.ServeJSON() | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	resp, err := serv.GetKubeconfigSecret(execution) | ||||
| 	if err != nil { | ||||
| 		// change code to 500 | ||||
| 		c.Ctx.Output.SetStatus(500) | ||||
| 		c.Data["json"] = map[string]string{"error": err.Error()} | ||||
| 		c.ServeJSON() | ||||
| 		return | ||||
| 	} | ||||
| 	if resp == nil { | ||||
| 		c.Ctx.Output.SetStatus(404) | ||||
| 		c.ServeJSON() | ||||
| 		return | ||||
| 	} | ||||
| 	 | ||||
| 	err = json.Unmarshal(resp,&data) | ||||
| 	if err != nil { | ||||
| 		// change code to 500 | ||||
| 		c.Ctx.Output.SetStatus(500) | ||||
| 		c.ServeJSON() | ||||
| 		c.Data["json"] = map[string]string{"error": err.Error()} | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	c.Data["json"] = data | ||||
| 	c.ServeJSON() | ||||
| } | ||||
|  | ||||
|  | ||||
| // @Title CreateKubeSecret | ||||
| // @Description Creat a secret from a Kubeconfig that will be associated to an Admiralty Target | ||||
| // @Param dc_id 	path	string 		true 	"which dc to contact" | ||||
| // @Param execution path 	string 		true	"execution id of the workflow" | ||||
| // @Param kubeconfig 	body	controllers.Kubeconfig 		true 	"Kubeconfig to use when creating secret" | ||||
| // @Success 200  | ||||
| // @router /secret/:dc_id/:execution [post] | ||||
| func (c *AdmiraltyController) CreateKubeSecret() { | ||||
| 	var kubeconfig 	Kubeconfig | ||||
| 	var respData	map[string]interface{} | ||||
|  | ||||
| 	data := c.Ctx.Input.CopyBody(100000) | ||||
|  | ||||
| 	err := json.Unmarshal(data, &kubeconfig) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Error when retrieving the data for kubeconfig from request") | ||||
| 		fmt.Println(err) | ||||
| 		c.Ctx.Output.SetStatus(500) | ||||
| 		c.Data["json"] = map[string]string{"error": err.Error()} | ||||
| 		c.ServeJSON() | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	dc_id := c.Ctx.Input.Param(":dc_id") | ||||
| 	execution := c.Ctx.Input.Param(":execution") | ||||
| 	_ = dc_id | ||||
|  | ||||
| 	serv, err := infrastructure.NewService() | ||||
| 	if err != nil { | ||||
| 		// change code to 500 | ||||
| 		c.Ctx.Output.SetStatus(500) | ||||
| 		c.Data["json"] = map[string]string{"error": err.Error()} | ||||
| 		c.ServeJSON() | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	resp, err := serv.CreateKubeconfigSecret(*kubeconfig.Data,execution) | ||||
| 	if err != nil { | ||||
| 		// change code to 500 | ||||
| 		c.Ctx.Output.SetStatus(500) | ||||
| 		c.Data["json"] = map[string]string{"error": err.Error()} | ||||
| 		c.ServeJSON() | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	err = json.Unmarshal(resp,&respData) | ||||
| 	c.Data["json"] = respData | ||||
| 	c.ServeJSON() | ||||
|  | ||||
| } | ||||
| @@ -14,6 +14,10 @@ type Infrastructure interface { | ||||
| 	CreateRoleBinding(ctx context.Context, ns string, roleBinding string, role string) error | ||||
| 	CreateRole(ctx context.Context, ns string, role string, groups [][]string, resources [][]string, verbs [][]string) error | ||||
| 	GetTargets(ctx context.Context) ([]string,error) | ||||
| 	CreateAdmiraltySource(executionId string) ([]byte, error) | ||||
| 	CreateKubeconfigSecret(kubeconfig string, executionId string) ([]byte, error)  | ||||
| 	GetKubeconfigSecret(executionId string) ([]byte, error) | ||||
| 	CreateAdmiraltyTarget(executionId string)([]byte,error) | ||||
| } | ||||
|  | ||||
| var _service = map[string]func() (Infrastructure, error){ | ||||
| @@ -27,3 +31,4 @@ func NewService() (Infrastructure, error) { | ||||
| 	} | ||||
| 	return service() | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,15 +1,19 @@ | ||||
| package infrastructure | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"context" | ||||
| 	"encoding/base64" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"html/template" | ||||
| 	"oc-datacenter/conf" | ||||
|  | ||||
| 	authv1 "k8s.io/api/authentication/v1" | ||||
| 	v1 "k8s.io/api/core/v1" | ||||
| 	rbacv1 "k8s.io/api/rbac/v1" | ||||
| 	apierrors "k8s.io/apimachinery/pkg/api/errors" | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/client-go/kubernetes" | ||||
| 	"k8s.io/client-go/rest" | ||||
| @@ -43,6 +47,34 @@ func NewKubernetesService() (Infrastructure, error) { | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| func NewRemoteKubernetesService(url string, ca string, cert string, key string) (Infrastructure, error) { | ||||
| 	decodedCa, _ := base64.StdEncoding.DecodeString(ca) | ||||
| 	decodedCert, _ := base64.StdEncoding.DecodeString(cert) | ||||
| 	decodedKey, _ := base64.StdEncoding.DecodeString(key) | ||||
|  | ||||
| 	config := &rest.Config{ | ||||
| 		Host: url + ":6443", | ||||
| 		TLSClientConfig: rest.TLSClientConfig{ | ||||
| 			CAData:   decodedCa, | ||||
| 			CertData: decodedCert, | ||||
| 			KeyData:  decodedKey, | ||||
| 		}, | ||||
| 	} | ||||
| 	// 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{ | ||||
| @@ -158,19 +190,16 @@ func (k *KubernetesService) GetToken(ctx context.Context, ns string, duration in | ||||
| 	return token.Status.Token, nil | ||||
| } | ||||
|  | ||||
| // Needs refactoring : | ||||
| //  - Retrieving the metada (in a method that Unmarshall the part of the json in a metadata object) | ||||
| func (k *KubernetesService) GetTargets(ctx context.Context) ([]string,error){ | ||||
|  | ||||
| 	var listTargets []string | ||||
| 	resp, err := k.Set.RESTClient(). | ||||
| 		Get(). | ||||
| 		AbsPath("/apis/multicluster.admiralty.io/v1alpha1/targets"). | ||||
| 		DoRaw(ctx) // from https://stackoverflow.com/questions/60764908/how-to-access-kubernetes-crd-using-client-go | ||||
| 	 | ||||
| 	resp, err := getCDRapiKube(*k.Set, ctx,"/apis/multicluster.admiralty.io/v1alpha1/targets") | ||||
| 	if err != nil { | ||||
| 		fmt.Println("TODO : handle the error generated when contacting kube API") | ||||
| 		fmt.Println("Error from k8s API : ", err) | ||||
| 		return nil,err | ||||
| 	} | ||||
|  | ||||
| 	fmt.Println(string(resp)) | ||||
| 	var targetDict map[string]interface{} | ||||
| 	err = json.Unmarshal(resp,&targetDict) | ||||
| @@ -201,8 +230,215 @@ func (k *KubernetesService) GetTargets(ctx context.Context) ([]string,error){ | ||||
|  | ||||
| 		listTargets = append(listTargets, metadata.Name) | ||||
| 	} | ||||
| 	// parse targets to retrieve the info we need  | ||||
| 	// fmt.Println(targetDict) | ||||
|  | ||||
| 	return listTargets,nil | ||||
|  | ||||
| } | ||||
|  | ||||
| // Admiralty Target allows a cluster to deploy pods to remote cluster  | ||||
| // | ||||
| // The remote  cluster must : | ||||
| // | ||||
| // - have declared a Source resource | ||||
| // | ||||
| // - have declared the same namespace as the one where the pods are created in the local cluster | ||||
| // | ||||
| // - have delcared a serviceAccount with sufficient permission to create pods  | ||||
| func (k *KubernetesService) CreateAdmiraltyTarget(executionId string)([]byte,error){ | ||||
| 	exists, err := k.GetKubeconfigSecret(executionId) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Error verifying kube-secret before creating target") | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if exists == nil { | ||||
| 		fmt.Println("Target needs to be binded to a secret in ns-",executionId) | ||||
| 		return nil, nil	// Maybe we could create a wrapper for errors and add more info to have | ||||
| 	} | ||||
| 	 | ||||
| 	var targetManifest string  | ||||
| 	var tpl bytes.Buffer | ||||
| 	tmpl, err := template.New("target"). | ||||
| 		Parse("{\"apiVersion\": \"multicluster.admiralty.io/v1alpha1\", \"kind\": \"Target\", \"metadata\": {\"name\": \"target-{{.ExecutionId}}\"}, \"spec\": { \"kubeconfigSecret\" :{\"name\": \"kube-secret-{{.ExecutionId}}\"}} }") | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Error creating the template for the target Manifest") | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	err = tmpl.Execute(&tpl, map[string]string{"ExecutionId":executionId}) | ||||
| 	targetManifest = tpl.String() | ||||
| 	resp, err := postCDRapiKube( | ||||
| 		*k.Set, | ||||
| 		context.TODO(), | ||||
| 		"/apis/multicluster.admiralty.io/v1alpha1/namespaces/ns-"+ executionId +"/targets", | ||||
| 		[]byte(targetManifest), | ||||
| 		map[string]string{"fieldManager":"kubectl-client-side-apply"}, | ||||
| 		map[string]string{"fieldValidation":"Strict"}, | ||||
| 	) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Error trying to create a Source on remote cluster : ", err , " : ", resp) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return resp, nil | ||||
| } | ||||
|  | ||||
|  | ||||
| // Admiralty Source allows a cluster to receive pods from a remote cluster | ||||
| // | ||||
| // The source must be associated to a serviceAccount, which will execute the pods locally. | ||||
| // This serviceAccount must have sufficient permission to create and patch pods | ||||
| // | ||||
| // This method is temporary to implement the use of Admiralty, but must be edited | ||||
| // to rather contact the oc-datacenter from the remote cluster to create the source | ||||
| // locally and retrieve the token for the serviceAccount | ||||
| func (k *KubernetesService) CreateAdmiraltySource(executionId string) ([]byte, error) { | ||||
| 	var sourceManifest string  | ||||
| 	var tpl bytes.Buffer | ||||
| 	tmpl, err := template.New("source"). | ||||
| 		Parse("{\"apiVersion\": \"multicluster.admiralty.io/v1alpha1\", \"kind\": \"Source\", \"metadata\": {\"name\": \"source-{{.ExecutionId}}\"}, \"spec\": {\"serviceAccountName\": \"sa-{{.ExecutionId}}\"} }") | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Error creating the template for the source Manifest") | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	err = tmpl.Execute(&tpl, map[string]string{"ExecutionId":executionId}) | ||||
| 	sourceManifest = tpl.String() | ||||
| 	 | ||||
| 	resp, err := postCDRapiKube( | ||||
| 		*k.Set, | ||||
| 		context.TODO(), | ||||
| 		"/apis/multicluster.admiralty.io/v1alpha1/namespaces/ns-"+ executionId +"/sources", | ||||
| 		[]byte(sourceManifest), | ||||
| 		map[string]string{"fieldManager":"kubectl-client-side-apply"}, | ||||
| 		map[string]string{"fieldValidation":"Strict"}, | ||||
| 	) | ||||
|  | ||||
| 	// We can add more info to the log with the content of resp if not nil | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Error trying to create a Source on remote cluster : ", err , " : ", resp) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return resp, nil | ||||
| } | ||||
|  | ||||
| // Create a secret from a kubeconfing. Use it to create the secret binded to an Admiralty | ||||
| // target, which must contain the serviceAccount's token value | ||||
| func (k *KubernetesService) CreateKubeconfigSecret(kubeconfig string, executionId string) ([]byte, error) { | ||||
| 	config, err := base64.StdEncoding.DecodeString(kubeconfig) | ||||
| 	// config, err := base64.RawStdEncoding.DecodeString(kubeconfig) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Error while encoding kubeconfig") | ||||
| 		fmt.Println(err) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	secretManifest := &v1.Secret{ | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			Name:      "kube-secret-" + executionId, | ||||
| 			Namespace: "ns-" + executionId, | ||||
| 		}, | ||||
| 		Data: map[string][]byte{ | ||||
| 			"config": config, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	exists, err := k.GetKubeconfigSecret(executionId) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Error verifying if kube secret exists in ns-", executionId) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if exists != nil { | ||||
| 		fmt.Println("kube-secret already exists in ns-", executionId) | ||||
| 		fmt.Println("Overriding existing kube-secret with a newer resource") | ||||
| 		// TODO : implement DeleteKubeConfigSecret(executionID) | ||||
| 		deleted, err := k.DeleteKubeConfigSecret(executionId) | ||||
| 		_ = deleted | ||||
| 		_ = err | ||||
| 	} | ||||
| 	resp, err := k.Set.CoreV1(). | ||||
| 				Secrets("ns-"+executionId). | ||||
| 				Create(context.TODO(),secretManifest,metav1.CreateOptions{}) | ||||
| 				 | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Error while trying to contact API to get secret kube-secret-"+executionId) | ||||
| 		fmt.Println(err) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	data, err := json.Marshal(resp) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Couldn't marshal resp from : ", data) | ||||
| 		fmt.Println(err) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return data, nil | ||||
| }  | ||||
|  | ||||
| func (k *KubernetesService) GetKubeconfigSecret(executionId string) ([]byte, error) { | ||||
| 	resp, err := k.Set.CoreV1(). | ||||
| 						Secrets("ns-"+executionId). | ||||
| 						Get(context.TODO(),"kube-secret-"+executionId,metav1.GetOptions{}) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		if(apierrors.IsNotFound(err)){ | ||||
| 			fmt.Println("kube-secret not found for execution ", executionId) | ||||
| 			return nil, nil | ||||
| 		} | ||||
| 		fmt.Println("Error while trying to contact API to get secret kube-secret-"+executionId) | ||||
| 		fmt.Println(err) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	data, err := json.Marshal(resp) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Couldn't marshal resp from : ", data) | ||||
| 		fmt.Println(err) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return data, nil | ||||
| } | ||||
|  | ||||
| func (k *KubernetesService) DeleteKubeConfigSecret(executionID string) ([]byte, error){ | ||||
|  | ||||
| 	return []byte{}, nil | ||||
| } | ||||
|  | ||||
| func getCDRapiKube(client kubernetes.Clientset, ctx context.Context, path string) ([]byte,error) { | ||||
| 	resp, err := client.RESTClient().Get(). | ||||
| 	AbsPath(path). | ||||
| 	DoRaw(ctx) // from https://stackoverflow.com/questions/60764908/how-to-access-kubernetes-crd-using-client-go | ||||
|  | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Error from k8s API when getting " + path + " : " , err) | ||||
| 		return nil,err | ||||
| 	} | ||||
|  | ||||
| 	return resp, nil | ||||
| } | ||||
|  | ||||
| func postCDRapiKube(client kubernetes.Clientset, ctx context.Context, path string, body []byte, params ...map[string]string) ([]byte, error){ | ||||
| 	req := client.RESTClient(). | ||||
| 				Post(). | ||||
| 				AbsPath(path). | ||||
| 				Body(body) | ||||
|  | ||||
| 	for _, param := range params { | ||||
| 		for k,v := range param { | ||||
| 			req = req.Param(k,v) | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	resp, err := req.DoRaw(ctx) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Error from k8s API when posting " + string(body) + " to " + path + " : " , err) | ||||
| 		return nil,err | ||||
| 	} | ||||
|  | ||||
| 	return resp, nil | ||||
| } | ||||
		Reference in New Issue
	
	Block a user