[NEED REFACTORING] added DynamicClient constructor to make API calls on CDRs
This commit is contained in:
		@@ -1,13 +1,11 @@
 | 
				
			|||||||
package infrastructure
 | 
					package infrastructure
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"encoding/base64"
 | 
						"encoding/base64"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"html/template"
 | 
					 | 
				
			||||||
	"oc-datacenter/conf"
 | 
						"oc-datacenter/conf"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -16,15 +14,42 @@ import (
 | 
				
			|||||||
	rbacv1 "k8s.io/api/rbac/v1"
 | 
						rbacv1 "k8s.io/api/rbac/v1"
 | 
				
			||||||
	apierrors "k8s.io/apimachinery/pkg/api/errors"
 | 
						apierrors "k8s.io/apimachinery/pkg/api/errors"
 | 
				
			||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
 | 
						"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 | 
				
			||||||
 | 
						"k8s.io/apimachinery/pkg/runtime/schema"
 | 
				
			||||||
	apply "k8s.io/client-go/applyconfigurations/core/v1"
 | 
						apply "k8s.io/client-go/applyconfigurations/core/v1"
 | 
				
			||||||
 | 
						"k8s.io/client-go/dynamic"
 | 
				
			||||||
	"k8s.io/client-go/kubernetes"
 | 
						"k8s.io/client-go/kubernetes"
 | 
				
			||||||
	"k8s.io/client-go/rest"
 | 
						"k8s.io/client-go/rest"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var gvrSources = schema.GroupVersionResource{Group: "multicluster.admiralty.io", Version: "v1alpha1", Resource: "sources"}
 | 
				
			||||||
 | 
					var gvrTargets = schema.GroupVersionResource{Group: "multicluster.admiralty.io", Version: "v1alpha1", Resource: "targets"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type KubernetesService struct {
 | 
					type KubernetesService struct {
 | 
				
			||||||
	Set 			*kubernetes.Clientset
 | 
						Set 			*kubernetes.Clientset
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewDynamicClient() (*dynamic.DynamicClient, 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),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dynamicClient, err := dynamic.NewForConfig(config)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, errors.New("Error creating Dynamic client: " + err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if dynamicClient == nil {
 | 
				
			||||||
 | 
							return nil, errors.New("Error creating Dynamic client: dynamicClient is nil")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return dynamicClient, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewKubernetesService() (Infrastructure, error) {
 | 
					func NewKubernetesService() (Infrastructure, error) {
 | 
				
			||||||
	config := &rest.Config{
 | 
						config := &rest.Config{
 | 
				
			||||||
		Host: conf.GetConfig().KubeHost + ":" + conf.GetConfig().KubePort,
 | 
							Host: conf.GetConfig().KubeHost + ":" + conf.GetConfig().KubePort,
 | 
				
			||||||
@@ -34,6 +59,7 @@ func NewKubernetesService() (Infrastructure, error) {
 | 
				
			|||||||
			KeyData:  []byte(conf.GetConfig().KubeData),
 | 
								KeyData:  []byte(conf.GetConfig().KubeData),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	// Create clientset
 | 
						// Create clientset
 | 
				
			||||||
	clientset, err := kubernetes.NewForConfig(config)
 | 
						clientset, err := kubernetes.NewForConfig(config)
 | 
				
			||||||
	fmt.Println("NewForConfig", clientset, err)
 | 
						fmt.Println("NewForConfig", clientset, err)
 | 
				
			||||||
@@ -44,6 +70,7 @@ func NewKubernetesService() (Infrastructure, error) {
 | 
				
			|||||||
		return nil, errors.New("Error creating Kubernetes client: clientset is nil")
 | 
							return nil, errors.New("Error creating Kubernetes client: clientset is nil")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &KubernetesService{
 | 
						return &KubernetesService{
 | 
				
			||||||
		Set: clientset,
 | 
							Set: clientset,
 | 
				
			||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
@@ -267,32 +294,73 @@ func (k *KubernetesService) CreateAdmiraltyTarget(context context.Context,execut
 | 
				
			|||||||
		return nil, nil	// Maybe we could create a wrapper for errors and add more info to have
 | 
							return nil, nil	// Maybe we could create a wrapper for errors and add more info to have
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	var targetManifest string 
 | 
						// var targetManifest string 
 | 
				
			||||||
	var tpl bytes.Buffer
 | 
						// var tpl bytes.Buffer
 | 
				
			||||||
	tmpl, err := template.New("target").
 | 
						// tmpl, err := template.New("target").
 | 
				
			||||||
		Parse("{\"apiVersion\": \"multicluster.admiralty.io/v1alpha1\", \"kind\": \"Target\", \"metadata\": {\"name\": \"target-{{.ExecutionId}}\"}, \"spec\": { \"kubeconfigSecret\" :{\"name\": \"kube-secret-{{.ExecutionId}}\"}} }")
 | 
						// 	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 := putCDRapiKube(
 | 
				
			||||||
 | 
						// 	*k.Set,
 | 
				
			||||||
 | 
						// 	context,
 | 
				
			||||||
 | 
						// 	"/apis/multicluster.admiralty.io/v1alpha1/namespaces/"+ executionId +"/targets",
 | 
				
			||||||
 | 
						// 	[]byte(targetManifest),
 | 
				
			||||||
 | 
						// 	map[string]string{"fieldManager":"kubectl-client-side-apply"},
 | 
				
			||||||
 | 
						// 	map[string]string{"fieldValidation":"Strict"},
 | 
				
			||||||
 | 
						// )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						target := map[string]interface{}{
 | 
				
			||||||
 | 
					        "apiVersion": "multicluster.admiralty.io/v1alpha1",
 | 
				
			||||||
 | 
					        "kind":       "Target",
 | 
				
			||||||
 | 
					        "metadata": map[string]interface{}{
 | 
				
			||||||
 | 
					            "name":      "target-"+executionId,
 | 
				
			||||||
 | 
					            "namespace": executionId,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "spec": map[string]interface{}{
 | 
				
			||||||
 | 
					            "kubeconfigSecret": map[string]string{
 | 
				
			||||||
 | 
									"name" : "kube-secret-"+executionId,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						body, err := json.Marshal(target)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("Error creating the template for the target Manifest")
 | 
							fmt.Println("Error creating the body from the source Manifest")
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = tmpl.Execute(&tpl, map[string]string{"ExecutionId":executionId})
 | 
						cli, err := NewDynamicClient()
 | 
				
			||||||
	targetManifest = tpl.String()
 | 
						if err != nil {
 | 
				
			||||||
	resp, err := putCDRapiKube(
 | 
							return nil, errors.New("Could not retrieve dynamic client when creating Admiralty Source : " + err.Error())
 | 
				
			||||||
		*k.Set,
 | 
						}
 | 
				
			||||||
		context,
 | 
					
 | 
				
			||||||
		"/apis/multicluster.admiralty.io/v1alpha1/namespaces/"+ executionId +"/targets",
 | 
						res, err := cli.Resource(gvrTargets).
 | 
				
			||||||
		[]byte(targetManifest),
 | 
										Namespace(executionId).
 | 
				
			||||||
		map[string]string{"fieldManager":"kubectl-client-side-apply"},
 | 
										Apply(context, 
 | 
				
			||||||
		map[string]string{"fieldValidation":"Strict"},
 | 
											"source-"+executionId,
 | 
				
			||||||
 | 
											&unstructured.Unstructured{Object: target},
 | 
				
			||||||
 | 
											metav1.ApplyOptions{
 | 
				
			||||||
 | 
												FieldManager: "kubectl-client-side-apply", 
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
					)
 | 
										)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("Error trying to create a Source on remote cluster : ", err , " : ", resp)
 | 
							fmt.Println("Error from k8s API when applying " + string(body) + " to " + gvrSources.String() + " : " , err)
 | 
				
			||||||
		return nil,err
 | 
							return nil,err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return resp, nil
 | 
						resByte, err := json.Marshal(res) 
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							// fmt.Println("Error trying to create a Source on remote cluster : ", err , " : ", res)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return resByte, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -305,35 +373,78 @@ func (k *KubernetesService) CreateAdmiraltyTarget(context context.Context,execut
 | 
				
			|||||||
// to rather contact the oc-datacenter from the remote cluster to create the source
 | 
					// to rather contact the oc-datacenter from the remote cluster to create the source
 | 
				
			||||||
// locally and retrieve the token for the serviceAccount
 | 
					// locally and retrieve the token for the serviceAccount
 | 
				
			||||||
func (k *KubernetesService) CreateAdmiraltySource(context context.Context,executionId string) ([]byte, error) {
 | 
					func (k *KubernetesService) CreateAdmiraltySource(context context.Context,executionId string) ([]byte, error) {
 | 
				
			||||||
	var sourceManifest string 
 | 
						// var sourceManifest string 
 | 
				
			||||||
	var tpl bytes.Buffer
 | 
						// var tpl bytes.Buffer
 | 
				
			||||||
	tmpl, err := template.New("source").
 | 
						// tmpl, err := template.New("source").
 | 
				
			||||||
		Parse("{\"apiVersion\": \"multicluster.admiralty.io/v1alpha1\", \"kind\": \"Source\", \"metadata\": {\"name\": \"source-{{.ExecutionId}}\"}, \"spec\": {\"serviceAccountName\": \"sa-{{.ExecutionId}}\"} }")
 | 
						// 	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
 | 
				
			||||||
 | 
						// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						source := map[string]interface{}{
 | 
				
			||||||
 | 
					        "apiVersion": "multicluster.admiralty.io/v1alpha1",
 | 
				
			||||||
 | 
					        "kind":       "Source",
 | 
				
			||||||
 | 
					        "metadata": map[string]interface{}{
 | 
				
			||||||
 | 
					            "name":      "source-"+executionId,
 | 
				
			||||||
 | 
					            "namespace": executionId,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "spec": map[string]interface{}{
 | 
				
			||||||
 | 
					            "serviceAccountName": "sa-"+executionId,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						body, err := json.Marshal(source)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("Error creating the template for the source Manifest")
 | 
							fmt.Println("Error creating the body from the source Manifest")
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = tmpl.Execute(&tpl, map[string]string{"ExecutionId":executionId})
 | 
						// err = tmpl.Execute(&tpl, map[string]string{"ExecutionId":executionId})
 | 
				
			||||||
	sourceManifest = tpl.String()
 | 
						// sourceManifest = tpl.String()
 | 
				
			||||||
 | 
						// resp, err := putCDRapiKube(
 | 
				
			||||||
 | 
						// 	*k.Set,
 | 
				
			||||||
 | 
						// 	context,
 | 
				
			||||||
 | 
						// 	"/apis/multicluster.admiralty.io/v1alpha1/namespaces/"+ executionId +"/sources",
 | 
				
			||||||
 | 
						// 	[]byte(sourceManifest),
 | 
				
			||||||
 | 
						// 	map[string]string{"fieldManager":"kubectl-client-side-apply"},
 | 
				
			||||||
 | 
						// 	map[string]string{"fieldValidation":"Strict"},
 | 
				
			||||||
 | 
						// )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	resp, err := putCDRapiKube(
 | 
						// params := []map[string]string{
 | 
				
			||||||
		*k.Set,
 | 
						// 	{"fieldManager":"kubectl-client-side-apply"},
 | 
				
			||||||
		context,
 | 
						// 	{"fieldValidation":"Strict"},
 | 
				
			||||||
		"/apis/multicluster.admiralty.io/v1alpha1/namespaces/"+ executionId +"/sources",
 | 
						// }
 | 
				
			||||||
		[]byte(sourceManifest),
 | 
						
 | 
				
			||||||
		map[string]string{"fieldManager":"kubectl-client-side-apply"},
 | 
						cli, err := NewDynamicClient()
 | 
				
			||||||
		map[string]string{"fieldValidation":"Strict"},
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, errors.New("Could not retrieve dynamic client when creating Admiralty Source : " + err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res, err := cli.Resource(gvrSources).
 | 
				
			||||||
 | 
										Namespace(executionId).
 | 
				
			||||||
 | 
										Apply(context, 
 | 
				
			||||||
 | 
											"source-"+executionId,
 | 
				
			||||||
 | 
											&unstructured.Unstructured{Object: source},
 | 
				
			||||||
 | 
											metav1.ApplyOptions{
 | 
				
			||||||
 | 
												FieldManager: "kubectl-client-side-apply", 
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
					)
 | 
										)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							fmt.Println("Error from k8s API when applying " + string(body) + " to " + gvrSources.String() + " : " , err)
 | 
				
			||||||
 | 
							return nil,err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// We can add more info to the log with the content of resp if not nil
 | 
						// We can add more info to the log with the content of resp if not nil
 | 
				
			||||||
 | 
						resByte, err := json.Marshal(res) 
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("Error trying to create a Source on remote cluster : ", err , " : ", resp)
 | 
							// fmt.Println("Error trying to create a Source on remote cluster : ", err , " : ", res)
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return resp, nil
 | 
						return resByte, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Create a secret from a kubeconfing. Use it to create the secret binded to an Admiralty
 | 
					// Create a secret from a kubeconfing. Use it to create the secret binded to an Admiralty
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user