diff options
Diffstat (limited to 'src/k8splugin/internal/app/client.go')
-rw-r--r-- | src/k8splugin/internal/app/client.go | 176 |
1 files changed, 166 insertions, 10 deletions
diff --git a/src/k8splugin/internal/app/client.go b/src/k8splugin/internal/app/client.go index 3555afdd..fa5fdfd5 100644 --- a/src/k8splugin/internal/app/client.go +++ b/src/k8splugin/internal/app/client.go @@ -14,31 +14,187 @@ limitations under the License. package app import ( - "errors" + "log" + "os" + "strings" - pkgerrors "github.com/pkg/errors" + utils "k8splugin/internal" + pkgerrors "github.com/pkg/errors" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" + "k8s.io/helm/pkg/tiller" ) -// GetKubeClient loads the Kubernetes configuation values stored into the local configuration file -var GetKubeClient = func(configPath string) (kubernetes.Clientset, error) { - var clientset *kubernetes.Clientset +type kubernetesClient struct { + clientSet *kubernetes.Clientset +} +// GetKubeClient loads the Kubernetes configuation values stored into the local configuration file +func (k *kubernetesClient) init(configPath string) error { if configPath == "" { - return *clientset, errors.New("config not passed and is not found in ~/.kube. ") + return pkgerrors.New("config not passed and is not found in ~/.kube. ") } config, err := clientcmd.BuildConfigFromFlags("", configPath) if err != nil { - return kubernetes.Clientset{}, pkgerrors.Wrap(err, "setConfig: Build config from flags raised an error") + return pkgerrors.Wrap(err, "setConfig: Build config from flags raised an error") + } + + k.clientSet, err = kubernetes.NewForConfig(config) + if err != nil { + return err + } + + return nil +} + +func (k *kubernetesClient) ensureNamespace(namespace string) error { + namespacePlugin, ok := utils.LoadedPlugins["namespace"] + if !ok { + return pkgerrors.New("No plugin for namespace resource found") + } + + symGetNamespaceFunc, err := namespacePlugin.Lookup("Get") + if err != nil { + return pkgerrors.Wrap(err, "Error fetching get namespace function") + } + + ns, _ := symGetNamespaceFunc.(func(string, string, kubernetes.Interface) (string, error))( + namespace, namespace, k.clientSet) + + if ns == "" { + log.Println("Creating " + namespace + " namespace") + symGetNamespaceFunc, err := namespacePlugin.Lookup("Create") + if err != nil { + return pkgerrors.Wrap(err, "Error fetching create namespace plugin") + } + namespaceResource := &utils.ResourceData{ + Namespace: namespace, + } + + _, err = symGetNamespaceFunc.(func(*utils.ResourceData, kubernetes.Interface) (string, error))( + namespaceResource, k.clientSet) + if err != nil { + return pkgerrors.Wrap(err, "Error creating "+namespace+" namespace") + } + } + return nil +} + +func (k *kubernetesClient) createKind(kind string, files []string, namespace string) ([]string, error) { + + log.Println("Processing items of Kind: " + kind) + + //Iterate over each file of a particular kind here + var resourcesCreated []string + for _, f := range files { + if _, err := os.Stat(f); os.IsNotExist(err) { + return nil, pkgerrors.New("File " + f + "does not exists") + } + + log.Println("Processing file: " + f) + + //Populate the namespace from profile instead of instance body + genericKubeData := &utils.ResourceData{ + YamlFilePath: f, + Namespace: namespace, + } + + typePlugin, ok := utils.LoadedPlugins[strings.ToLower(kind)] + if !ok { + return nil, pkgerrors.New("No plugin for kind " + kind + " found") + } + + symCreateResourceFunc, err := typePlugin.Lookup("Create") + if err != nil { + return nil, pkgerrors.Wrap(err, "Error fetching "+kind+" plugin") + } + + createdResourceName, err := symCreateResourceFunc.(func(*utils.ResourceData, kubernetes.Interface) (string, error))( + genericKubeData, k.clientSet) + if err != nil { + return nil, pkgerrors.Wrap(err, "Error in plugin "+kind+" plugin") + } + log.Print(createdResourceName + " created") + resourcesCreated = append(resourcesCreated, createdResourceName) + } + + return resourcesCreated, nil +} + +func (k *kubernetesClient) createResources(resMap map[string][]string, + namespace string) (map[string][]string, error) { + + err := k.ensureNamespace(namespace) + if err != nil { + return nil, pkgerrors.Wrap(err, "Creating Namespace") + } + + createdResourceMap := make(map[string][]string) + // Create all the known kinds in the InstallOrder + for _, kind := range tiller.InstallOrder { + files, ok := resMap[kind] + if !ok { + log.Println("Kind " + kind + " not found. Skipping...") + continue + } + + resourcesCreated, err := k.createKind(kind, files, namespace) + if err != nil { + return nil, pkgerrors.Wrap(err, "Error creating kind: "+kind) + } + + createdResourceMap[kind] = resourcesCreated + delete(resMap, kind) } - clientset, err = kubernetes.NewForConfig(config) + //Create the remaining kinds from the resMap + for kind, files := range resMap { + resourcesCreated, err := k.createKind(kind, files, namespace) + if err != nil { + return nil, pkgerrors.Wrap(err, "Error creating kind: "+kind) + } + + createdResourceMap[kind] = resourcesCreated + delete(resMap, kind) + } + + return createdResourceMap, nil +} + +func (k *kubernetesClient) deleteKind(kind string, resources []string, namespace string) error { + log.Println("Deleting items of Kind: " + kind) + + typePlugin, ok := utils.LoadedPlugins[strings.ToLower(kind)] + if !ok { + return pkgerrors.New("No plugin for resource " + kind + " found") + } + + symDeleteResourceFunc, err := typePlugin.Lookup("Delete") if err != nil { - return *clientset, err + return pkgerrors.Wrap(err, "Error fetching "+kind+" plugin") + } + + for _, res := range resources { + log.Println("Deleting resource: " + res) + err = symDeleteResourceFunc.(func(string, string, kubernetes.Interface) error)( + res, namespace, k.clientSet) + if err != nil { + return pkgerrors.Wrap(err, "Error destroying "+res) + } + } + return nil +} + +func (k *kubernetesClient) deleteResources(resMap map[string][]string, namespace string) error { + //TODO: Investigate if deletion should be in a particular order + for kind, resourceNames := range resMap { + err := k.deleteKind(kind, resourceNames, namespace) + if err != nil { + return pkgerrors.Wrap(err, "Deleting resources") + } } - return *clientset, nil + return nil } |