github.com/profzone/eden-framework@v1.0.10/internal/project/deployment.go (about) 1 package project 2 3 import ( 4 "context" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "github.com/fatih/color" 9 "github.com/profzone/eden-framework/internal/k8s" 10 "github.com/sirupsen/logrus" 11 "gopkg.in/yaml.v2" 12 "io/ioutil" 13 apiv1 "k8s.io/api/core/v1" 14 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 15 "k8s.io/apimachinery/pkg/types" 16 "k8s.io/client-go/kubernetes" 17 "k8s.io/client-go/tools/clientcmd" 18 "strings" 19 ) 20 21 func ProcessDeployment(p *Project, env, kubeConfig, deployConfig, serviceConfig string) error { 22 if env == "" { 23 return errors.New("deployment must specify a environment name") 24 } 25 envVars := LoadEnv(env, p.Feature) 26 27 ctx, _ := context.WithCancel(context.Background()) 28 config, err := clientcmd.BuildConfigFromFlags("", kubeConfig) 29 if err != nil { 30 return err 31 } 32 clientSet, err := kubernetes.NewForConfig(config) 33 if err != nil { 34 return err 35 } 36 37 // Get Deployment 38 deployment, patch, err := k8s.MakeDeployment(deployConfig) 39 if err != nil { 40 return err 41 } 42 43 for key, val := range envVars { 44 deployment.Spec.Template.Spec.Containers[0].Env = append(deployment.Spec.Template.Spec.Containers[0].Env, apiv1.EnvVar{ 45 Name: key, 46 Value: val, 47 }) 48 } 49 patch = patchEnvVars(patch, envVars) 50 51 deploymentsClient := clientSet.AppsV1().Deployments(deployment.Namespace) 52 _, err = deploymentsClient.Get(ctx, deployment.Name, metav1.GetOptions{}) 53 if err != nil { 54 // Create Deployment 55 fmt.Println("Creating deployment...") 56 deployment, err = deploymentsClient.Create(ctx, deployment, metav1.CreateOptions{}) 57 if err != nil { 58 return err 59 } 60 fmt.Printf("Created deployment %s.\n", deployment.GetObjectMeta().GetName()) 61 } else { 62 // Patch Deployment 63 fmt.Println("Updating deployment...") 64 data, err := json.Marshal(patch) 65 if err != nil { 66 return err 67 } 68 deployment, err = deploymentsClient.Patch(ctx, deployment.Name, types.StrategicMergePatchType, data, metav1.PatchOptions{}) 69 if err != nil { 70 return err 71 } 72 fmt.Printf("Updated deployment %s.\n", deployment.GetObjectMeta().GetName()) 73 } 74 75 SetEnv(EnvKeyDeploymentUID, string(deployment.UID)) 76 77 // Get Service 78 service, patch, err := k8s.MakeService(serviceConfig) 79 if err != nil { 80 return err 81 } 82 servicesClient := clientSet.CoreV1().Services(service.Namespace) 83 _, err = servicesClient.Get(ctx, service.Name, metav1.GetOptions{}) 84 if err != nil { 85 // Create Service 86 fmt.Println("Creating service...") 87 service, err = servicesClient.Create(ctx, service, metav1.CreateOptions{}) 88 if err != nil { 89 return err 90 } 91 fmt.Printf("Created service %s.\n", service.GetObjectMeta().GetName()) 92 } else { 93 // Patch Service 94 fmt.Println("Updating service...") 95 data, err := json.Marshal(patch) 96 if err != nil { 97 return err 98 } 99 service, err = servicesClient.Patch(ctx, service.Name, types.StrategicMergePatchType, data, metav1.PatchOptions{}) 100 if err != nil { 101 return err 102 } 103 fmt.Printf("Updated service %s.\n", service.GetObjectMeta().GetName()) 104 } 105 return nil 106 } 107 108 func LoadEnv(envName string, feature string) map[string]string { 109 defaultEnv := loadEnvFromFiles("default", feature) 110 if envName != "" { 111 extendEnv := loadEnvFromFiles(envName, feature) 112 defaultEnv = mergeEnvVars(defaultEnv, extendEnv) 113 } 114 115 return defaultEnv 116 } 117 118 func loadEnvFromFiles(envName string, feature string) map[string]string { 119 defaultEnv := loadEnvFromFile(envName) 120 if feature != "" { 121 extendEnv := loadEnvFromFile(envName + "-" + feature) 122 defaultEnv = mergeEnvVars(defaultEnv, extendEnv) 123 } 124 125 return defaultEnv 126 } 127 128 func loadEnvFromFile(envName string) map[string]string { 129 filename := "build/configs/" + strings.ToLower(envName) + ".yml" 130 logrus.Infof("try to load env vars from %s ...\n", color.GreenString(filename)) 131 envFileContent, err := ioutil.ReadFile(filename) 132 if err != nil { 133 return nil 134 } 135 136 var envVars map[string]string 137 err = yaml.Unmarshal(envFileContent, &envVars) 138 if err != nil { 139 panic(err) 140 } 141 for key, value := range envVars { 142 SetEnv(key, value) 143 } 144 return envVars 145 } 146 147 func mergeEnvVars(self map[string]string, source map[string]string) map[string]string { 148 for key, val := range source { 149 self[key] = val 150 } 151 return self 152 } 153 154 func patchEnvVars(patch map[string]interface{}, envVars map[string]string) map[string]interface{} { 155 envs := make([]map[string]string, 0) 156 for key, val := range envVars { 157 envs = append(envs, map[string]string{ 158 "name": key, 159 "value": val, 160 }) 161 } 162 patch["spec"].(map[string]interface{})["template"].(map[string]interface{})["spec"].(map[string]interface{})["containers"].([]interface{})[0].(map[string]interface{})["env"] = envs 163 164 return patch 165 }