SKD : https://pkg.go.dev/helm.sh/helm/v3@v3.7.2/pkg/action
参考博文 : https://stackoverflow.com/questions/45692719/samples-on-kubernetes-helm-golang-client
package main
import (
"fmt"
"log"
"os"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/cli"
)
func main() {
chartPath := "./charts.tgz"
namespace := "default"
releaseName := "main-sky-beta"
settings := cli.New()
actionConfig := new(action.Configuration)
// You can pass an empty string instead of settings.Namespace() to list
// all namespaces
if err := actionConfig.Init(settings.RESTClientGetter(), namespace,
os.Getenv("HELM_DRIVER"), log.Printf); err != nil {
log.Printf("%+v", err)
os.Exit(1)
}
// define values
vals := map[string]interface{}{
"namespace": namespace,
"replicaCount": "1",
"image": map[string]interface{}{
"name": "image",
"pullPolicy": "IfNotPresent",
},
"nameOverride": releaseName,
"fullnameOverride": releaseName,
"service": map[string]interface{}{
"type": "ClusterIP",
"port": "8080",
},
"hostAliases": map[string]interface{}{
"hostAliasesSet": false,
"hostAliasesMap": "",
},
"imagePull": map[string]interface{}{
"secretsSet": true,
"secrets": "secret-harbor",
},
"envConfig": map[string]interface{}{
"configSet": false,
"config": "",
},
"resources": map[string]interface{}{
"resourcesSet": false,
"requests": map[string]interface{}{
"memory": "",
"cpu": "",
},
"limits": map[string]interface{}{
"memory": "",
"cpu": "",
},
"affinity": map[string]interface{}{
"affinitySet": false,
"key": "",
"operator": "In",
"values": "",
},
"tolerations": map[string]interface{}{
"tolerationsSet": false,
"key": "__TOLERATIONS_KEY__",
"operator": "Equal",
"value": "__TOLERATIONS_VALUE__",
"effect": "NoSchedule",
},
"livenessProbe": map[string]interface{}{
"livenessGetSet": false,
"livenessGet": "__LIVENESS_GET__",
"livenessCommandSet": false,
"livenessCommand": "__LIVENESS_COMMAND__",
},
"command": map[string]interface{}{
"commandSet": false,
"startCommand": "__COMMAND__",
},
"AnnoTations": map[string]interface{}{
"AnnoTationSet": false,
},
},
}
// load chart from the path
chart, err := loader.Load(chartPath)
if err != nil {
fmt.Println(err)
panic(err)
}
client := action.NewInstall(actionConfig)
client.Namespace = namespace
client.ReleaseName = releaseName
// client.DryRun = true - very handy!
// install the chart here
rel, err := client.Run(chart, vals)
if err != nil {
panic(err)
}
log.Printf("Installed Chart from path: %s in namespace: %s\n", rel.Name, rel.Namespace)
// this will confirm the values set during installation
log.Println(rel.Config)
}
client-go - 资源获取
SDK : https://pkg.go.dev/k8s.io/api@v0.22.4
参考博文 : https://stackoverflow.com/questions/40975307/how-to-watch-events-on-a-kubernetes-service-using-its-go-client
package main
import (
"context"
"fmt"
"log"
"time"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
func list() {
// config
configPath := "etc/kube.conf"
config, err := clientcmd.BuildConfigFromFlags("", configPath)
if err != nil {
log.Fatal(err)
}
clientSet, err := kubernetes.NewForConfig(config)
if err != nil {
log.Fatal(err)
}
// 查看Node信息
fmt.Println("*****************************************************************")
nodeList, err := clientSet.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
if err != nil {
log.Fatal(err)
}
for _, node := range nodeList.Items {
fmt.Printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s,\n",
node.Name,
node.Status.Phase,
node.Status.Addresses,
node.Status.NodeInfo.OSImage,
node.Status.NodeInfo.KubeletVersion,
node.Status.NodeInfo.OperatingSystem,
node.Status.NodeInfo.Architecture,
node.CreationTimestamp,
)
}
// 查看Namespace
fmt.Println("*****************************************************************")
namespaceList, err := clientSet.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{})
if err != nil {
log.Fatal(err)
}
for _, namespace := range namespaceList.Items {
fmt.Println(namespace.Name, namespace.CreationTimestamp, namespace.Status.Phase)
}
// 查看Service
fmt.Println("*****************************************************************")
// Services("") 传递指定的namespace
serviceList, err := clientSet.CoreV1().Services("").List(context.TODO(), metav1.ListOptions{})
if err != nil {
log.Fatal(err)
}
for _, service := range serviceList.Items {
fmt.Println(service.Name, service.Spec.Type, service.CreationTimestamp, service.Spec.Ports)
}
// 查看deployment
fmt.Println("*****************************************************************")
// Deployments("") 传递指定的namespace
deploymentList, err := clientSet.AppsV1().Deployments("").List(context.TODO(), metav1.ListOptions{})
if err != nil {
log.Fatal(err)
}
for _, deployment := range deploymentList.Items {
fmt.Println(deployment.Namespace, deployment.Name, deployment.CreationTimestamp, deployment.Spec.Selector.MatchLabels, deployment.Status.Replicas, deployment.Status.AvailableReplicas)
}
// Watch deployment 资源变动
fmt.Println("*****************************************************************")
deploymentListW, errw := clientSet.AppsV1().Deployments("default").Watch(context.TODO(), metav1.ListOptions{Watch: true, LabelSelector: "app=demoappv10"})
if errw != nil {
log.Fatal(err)
}
for event := range deploymentListW.ResultChan() {
fmt.Printf("Type: %v\n", event.Type)
p, ok := event.Object.(*v1.Pod)
if !ok {
log.Fatal("unexpected type")
}
fmt.Println(p.Status.ContainerStatuses)
fmt.Println(p.Status.Phase)
}
// Watch Pod 资源变动
fmt.Println("*****************************************************************")
label := "app=demoapp"
podListW, errw := clientSet.CoreV1().Pods("default").Watch(context.TODO(), metav1.ListOptions{LabelSelector: label})
if errw != nil {
log.Fatal(err)
}
go func() {
for event := range podListW.ResultChan() {
fmt.Printf("Type: %v\n", event.Type)
p, ok := event.Object.(*v1.Pod)
if !ok {
log.Fatal("unexpected type")
}
fmt.Println(p.Status.ContainerStatuses)
fmt.Println(p.Status.Phase)
}
}()
time.Sleep(5 * time.Second)
}
Helm3 Client工具
部署功能
- server
实现 helm upgrade --install 功能的逻辑:
由于helm.sh SDK未直接提供 upgrade --install 的方法,所以需要自行使用 NewHistory 获取release是否存在,若存在则调用 NewUpgrade 方法,若不存在则调用 NewInstall 方法;
package main
import (
"encoding/json"
"fmt"
"log"
"os"
"io/ioutil"
"net/http"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/cli/output"
"helm.sh/helm/v3/pkg/storage/driver"
)
var tmp string
var outfmt output.Format
type Image struct {
Name string `json:"name"`
PullPolicy string `json:"pullPolicy"`
}
type Service struct {
Type string `json:"type"`
Port string `json:"port"`
}
type HostAliases struct {
HostAliasesSet bool `json:"hostAliasesSet"`
// HostAliasesMap map[string]interface{} `json:"hostAliasesMap"`
HostAliasesMap string `json:"hostAliasesMap"`
}
type ImagePull struct {
SecretsSet bool `json:"secretsSet"`
Secrets string `json:"secrets"`
}
type EnvConfig struct {
ConfigSet bool `json:"configSet"`
Config string `json:"config"`
}
type Requests struct {
Memory string `json:"memory"`
Cpu string `json:"cpu"`
}
type Limits struct {
Memory string `json:"memory"`
Cpu string `json:"cpu"`
}
type Resources struct {
ResourcesSet bool `json:"resourcesSet"`
Requests *Requests `json:"requests"`
Limits *Limits `json:"limits"`
}
type Affinity struct {
AffinitySet bool `json:"affinitySet"`
Key string `json:"key"`
Operator string `json:"operator"`
Values string `json:"values"`
}
type Tolerations struct {
TolerationsSet bool `json:"tolerationsSet"`
Key string `json:"key"`
Operator string `json:"operator"`
Values string `json:"values"`
Effect string `json:"effect"`
}
type LivenessProbe struct {
LivenessGetSet bool `json:"livenessGetSet"`
LivenessGet string `json:"livenessGet"`
LivenessCommandSet bool `json:"livenessCommandSet"`
LivenessCommand string `json"livenessCommand"`
}
type Command struct {
CommandSet bool `json:"commandSet"`
StartCommand string `json:"startCommand'`
}
type AnnoTations struct {
AnnoTationSet bool `json:"AnnoTationSet"`
AnnoTationExplain string `json:"AnnoTationExplain"`
}
type PipeParams struct {
Namespace string `json:"namespace"`
ReplicaCount string `json:"replicaCount"`
// Image map[string]interface{} `json:"image"`
Image Image `json:"image"`
NameOverride string `json:"nameOverride"`
FullnameOverride string `json:"fullnameOverride"`
Service Service `json:"service"`
HostAliases HostAliases `json:"hostAliases"`
ImagePull ImagePull `json:"imagePull"`
EnvConfig EnvConfig `json:"envConfig"`
Resources Resources `json:"resources"`
Affinity Affinity `json:"affinity"`
Tolerations Tolerations `json:"tolerations"`
LivenessProbe LivenessProbe `json:"livenessProbe"`
Command Command `json:"command"`
AnnoTations AnnoTations `json:AnnoTations`
}
func Helm_Upgrade(args map[string]interface{}, namespace string, releaseName string) {
fmt.Println("args:", args)
chartPath := "./charts.tgz"
settings := cli.New()
actionConfig := new(action.Configuration)
// You can pass an empty string instead of settings.Namespace() to list
// all namespaces
if err := actionConfig.Init(settings.RESTClientGetter(), namespace,
os.Getenv("HELM_DRIVER"), log.Printf); err != nil {
log.Printf("%+v", err)
os.Exit(1)
}
// define values
// load chart from the path
chart, err := loader.Load(chartPath)
if err != nil {
fmt.Println(err)
panic(err)
}
client := action.NewUpgrade(actionConfig)
fmt.Println(namespace, releaseName)
client.Namespace = namespace
client.Install = true
// client.DryRun = true - very handy!
// Support reading values from STDIN for `upgrade` command
if client.Install {
// If a release does not exist, install it.
histClient := action.NewHistory(actionConfig)
histClient.Max = 1
if _, err := histClient.Run(releaseName); err == driver.ErrReleaseNotFound {
fmt.Println("Start Installation ...", releaseName)
// Only print this to stdout for table output
fmt.Println("Release does not exist. Installing it now")
instClient := action.NewInstall(actionConfig)
instClient.Namespace = namespace
instClient.ReleaseName = releaseName
// instClient.DryRun = client.DryRun
instClient.Timeout = 5000
instClient.Wait = true
rel, err := instClient.Run(chart, args)
if err != nil {
panic(err)
}
fmt.Println(rel.Info)
} else {
fmt.Println("Start Upgrate ...", releaseName)
// install the chart here
rel, err := client.Run(releaseName, chart, args)
if err != nil {
panic(err)
}
// fmt.Println(rel.Info.Notes)
fmt.Println(rel.Info.LastDeployed)
log.Printf("Installed Chart from path: %s in namespace: %s\n", rel.Name, rel.Namespace)
}
}
}
// http
func PipeHook(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
fmt.Println("method:", r.Method)
body, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Printf("read body err, %v\n", err)
return
}
// println("json:", string(body))
tmp := string(body)
var struct_tmp PipeParams
err = json.Unmarshal([]byte(tmp), &struct_tmp)
if err != nil {
fmt.Println(err)
} else {
var resMap map[string]interface{}
err := json.Unmarshal([]byte(tmp), &resMap)
if err != nil {
fmt.Println(err)
}
Helm_Upgrade(resMap, struct_tmp.Namespace, struct_tmp.NameOverride)
// Get_Release()
}
}
func main() {
http.HandleFunc("/pipeline/", PipeHook)
err := http.ListenAndServe(":9090", nil)
if err != nil {
fmt.Printf("http server failed, err:%v\n", err)
return
}
}
- Client
curl 127.0.0.1:9090/pipeline/ -X POST -d '{
"namespace": "default",
"replicaCount": "1",
"image": {
"name": "image",
"pullPolicy": "IfNotPresent"
},
"nameOverride": "main-sky-test",
"fullnameOverride": "main-sky-test",
"service": {
"type": "ClusterIP",
"port": "8080"
},
"hostAliases": {
"hostAliasesSet": false,
"hostAliasesMap": ""
},
"imagePull": {
"secretsSet": true,
"secrets": "secret-harbor"
},
"envConfig": {
"configSet": false,
"config": ""
},
"resources": {
"resourcesSet": false,
"requests": {
"memory": "",
"cpu": ""
},
"limits": {
"memory": "",
"cpu": ""
}
},
"affinity": {
"affinitySet": false,
"key": "",
"operator": "In",
"values": ""
},
"tolerations": {
"tolerationsSet": false,
"key": "__TOLERATIONS_KEY__",
"operator": "Equal",
"value": "__TOLERATIONS_VALUE__",
"effect": "NoSchedule"
},
"livenessProbe": {
"livenessGetSet": false,
"livenessGet": "__LIVENESS_GET__",
"livenessCommandSet": false,
"livenessCommand": "__LIVENESS_COMMAND__"
},
"command": {
"commandSet": false,
"startCommand": "__COMMAND__"
},
"AnnoTations": {
"AnnoTationSet": false,
"AnnoTationExplain": ""
}
}' --header "Content-Type: application/json"
部署及资源Watch功能
出于让客户端可以看到各个资源部署状态,故增加对 Deployment、Pod资源Watch机制;
- server
package main
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/cli/output"
"helm.sh/helm/v3/pkg/storage/driver"
appsV1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
// 操纵K8S每个方法同一超时时长
// var timeout int = 5
type Image struct {
Name string `json:"name"`
PullPolicy string `json:"pullPolicy"`
}
type Service struct {
Type string `json:"type"`
Port string `json:"port"`
}
type HostAliases struct {
HostAliasesSet bool `json:"hostAliasesSet"`
HostAliasesMap string `json:"hostAliasesMap"`
}
type ImagePull struct {
SecretsSet bool `json:"secretsSet"`
Secrets string `json:"secrets"`
}
type EnvConfig struct {
ConfigSet bool `json:"configSet"`
Config string `json:"config"`
}
type Requests struct {
Memory string `json:"memory"`
Cpu string `json:"cpu"`
}
type Limits struct {
Memory string `json:"memory"`
Cpu string `json:"cpu"`
}
type Resources struct {
ResourcesSet bool `json:"resourcesSet"`
Requests *Requests `json:"requests"`
Limits *Limits `json:"limits"`
}
type Affinity struct {
AffinitySet bool `json:"affinitySet"`
Key string `json:"key"`
Operator string `json:"operator"`
Values string `json:"values"`
}
type Tolerations struct {
TolerationsSet bool `json:"tolerationsSet"`
Key string `json:"key"`
Operator string `json:"operator"`
Values string `json:"values"`
Effect string `json:"effect"`
}
type LivenessProbe struct {
LivenessGetSet bool `json:"livenessGetSet"`
LivenessGet string `json:"livenessGet"`
LivenessCommandSet bool `json:"livenessCommandSet"`
LivenessCommand string `json:"livenessCommand"`
}
type Command struct {
CommandSet bool `json:"commandSet"`
StartCommand string `json:"startCommand"`
}
type AnnoTations struct {
AnnoTationSet bool `json:"AnnoTationSet"`
AnnoTationExplain string `json:"AnnoTationExplain"`
}
type PipeParams struct {
Namespace string `json:"namespace"`
ReplicaCount string `json:"replicaCount"`
// Image map[string]interface{} `json:"image"`
Image Image `json:"image"`
NameOverride string `json:"nameOverride"`
FullnameOverride string `json:"fullnameOverride"`
Service Service `json:"service"`
HostAliases HostAliases `json:"hostAliases"`
ImagePull ImagePull `json:"imagePull"`
EnvConfig EnvConfig `json:"envConfig"`
Resources Resources `json:"resources"`
Affinity Affinity `json:"affinity"`
Tolerations Tolerations `json:"tolerations"`
LivenessProbe LivenessProbe `json:"livenessProbe"`
Command Command `json:"command"`
AnnoTations AnnoTations `json:"AnnoTations"`
}
//
type Deployment struct {
// Resources string `json:"Resources"`
Name string `json:"Name"`
Ready string `json:"Ready"`
Avatlable string `json:"Avatlable"`
Age metav1.Time `json:"Age"`
Image string `json:"Image"`
}
type JsonResponse struct {
Deployment Deployment `json:"Deployment"`
Pod []interface{} `json:"Pod"`
}
// TODO
/*
Helm 状态返回
Helm 状态回滚
*/
type JsonResult struct {
Code int `json:"code"`
Msg string `json:"msg"`
Deployment JsonResponse `json:"deployment"`
}
// 加载配置文件
func K8s_Conf() (*kubernetes.Clientset, error) {
configPath := "etc/kube.conf"
config, err := clientcmd.BuildConfigFromFlags("", configPath)
if err != nil {
log.Fatal(err)
}
clientSet, err := kubernetes.NewForConfig(config)
if err != nil {
log.Fatal(err)
}
return clientSet, err
}
func Pod_Watch(name, namespace string) []interface{} {
// var podstatus Pod
var test []interface{}
label := "app.kubernetes.io/name=" + name
// label := "app=demoapp"
timeout := new(int64)
*timeout = 8
clientSet, err := K8s_Conf()
if err != nil {
log.Fatal(err)
}
// fmt.Println("*****************************************************************")
podListW, errw := clientSet.CoreV1().Pods(namespace).Watch(context.TODO(), metav1.ListOptions{LabelSelector: label, TimeoutSeconds: timeout})
if errw != nil {
log.Fatal(err)
}
// go func() {
for event := range podListW.ResultChan() {
// fmt.Printf("Type: %v\n", event.Type)
p, ok := event.Object.(*v1.Pod)
if !ok {
log.Fatal("unexpected type")
}
pname := p.Name // demoappv10-6ff964cbff-hmsb8
pstatus := p.Status.Phase // Running
reason := p.Status.StartTime
fmt.Printf("==> v1/Pod(related)\nNAME\t\t\t\t\tSTATUS\t\t\tAGE\n%s\t\t%s\t\t\t%v\t\n", pname, pstatus, reason)
reasonstring := fmt.Sprintf("%v", p.Status.StartTime)
pod := map[string]interface{}{
pname: []string{
string(pstatus), reasonstring,
},
}
// fmt.Println(pod)
test = append(test, pod)
}
return test
}
func K8s_Client(name, namespace string) JsonResponse {
var result JsonResponse
clientSet, err := K8s_Conf()
if err != nil {
log.Fatal(err)
}
fmt.Println("*****************************************************************")
label := "app.kubernetes.io/name=" + name
timeout := new(int64)
*timeout = 2
deploymentListW, errw := clientSet.AppsV1().Deployments(namespace).Watch(context.TODO(), metav1.ListOptions{LabelSelector: label, TimeoutSeconds: timeout})
if errw != nil {
log.Fatal(err)
}
for event := range deploymentListW.ResultChan() {
fmt.Printf("Type: %v\n", event.Type)
p, ok := event.Object.(*appsV1.Deployment)
if !ok {
log.Fatal("unexpected type")
}
// dns := p.Namespace
dna := p.Name
dreplicas := p.Status.Replicas
dreadyreplicas := p.Status.ReadyReplicas
davailablereplicas := p.Status.AvailableReplicas
dcreationtimestamp := p.CreationTimestamp
dgetimage := p.Spec.Template.Spec.Containers[0].Image
client_result := fmt.Sprintf("*****************************************************************\nRESOURCES:\n===> v1/Deployment\nNAME\t\tREADY\tAVAILABLE\tAGE\t\t\t\t\tIMAGE\n%s\t%v/%v\t%v\t\t%v\t\t%v\n", dna, dreplicas, dreadyreplicas, davailablereplicas, dcreationtimestamp, dgetimage)
fmt.Println(client_result)
result.Deployment.Name = p.Name
result.Deployment.Ready = fmt.Sprintf("%v/%v", p.Status.ReadyReplicas, p.Status.AvailableReplicas)
result.Deployment.Avatlable = fmt.Sprintf("%v", p.Status.AvailableReplicas)
result.Deployment.Age = p.CreationTimestamp
result.Deployment.Image = p.Spec.Template.Spec.Containers[0].Image
fmt.Println(result)
fmt.Println(name)
result.Pod = Pod_Watch(name, namespace)
if dreadyreplicas != dreplicas {
// 监视 Pod资源变动
fmt.Println("Pod_Watch")
result.Pod = Pod_Watch(name, namespace)
}
}
return result
}
var tmp string
var outfmt output.Format
func Helm_Upgrade(args map[string]interface{}, namespace string, releaseName string) JsonResult {
var result JsonResult
fmt.Println("args:", args)
chartPath := "./charts.tgz"
settings := cli.New()
actionConfig := new(action.Configuration)
// You can pass an empty string instead of settings.Namespace() to list
// all namespaces
if err := actionConfig.Init(settings.RESTClientGetter(), namespace,
os.Getenv("HELM_DRIVER"), log.Printf); err != nil {
log.Printf("%+v", err)
os.Exit(1)
}
// define values
// load chart from the path
chart, err := loader.Load(chartPath)
if err != nil {
fmt.Println(err)
panic(err)
}
client := action.NewUpgrade(actionConfig)
fmt.Println(namespace, releaseName)
client.Namespace = namespace
client.Install = true
client.Timeout = 30
// client.DryRun = true - very handy!
// Fixes #7002 - Support reading values from STDIN for `upgrade` command
// Must load values AFTER determining if we have to call install so that values loaded from stdin are are not read twice
if client.Install {
// If a release does not exist, install it.
histClient := action.NewHistory(actionConfig)
histClient.Max = 1
if _, err := histClient.Run(releaseName); err == driver.ErrReleaseNotFound {
fmt.Println("Start Installation ...", releaseName)
// Only print this to stdout for table output
fmt.Println("Release does not exist. Installing it now")
instClient := action.NewInstall(actionConfig)
instClient.Namespace = namespace
instClient.ReleaseName = releaseName
// instClient.DryRun = client.DryRun
instClient.Timeout = 30
// instClient.Wait = true
rel, err := instClient.Run(chart, args)
if err != nil {
panic(err)
}
fmt.Println(rel.Info)
msg := "Install success" + releaseName + "in" + namespace
result.Code = 200
result.Msg = msg
result.Deployment = K8s_Client(releaseName, namespace)
return result
} else {
fmt.Println("Start Upgrate ...", releaseName)
rel, err := client.Run(releaseName, chart, args)
if err != nil {
panic(err)
}
fmt.Println(rel.Info.LastDeployed)
log.Printf("Installed Chart from path: %s in namespace: %s\n", rel.Name, rel.Namespace)
// this will confirm the values set during installation
// log.Println(rel.Config)
msg := "Upgrate success " + releaseName + " in " + namespace
result.Code = 200
result.Msg = msg
result.Deployment = K8s_Client(releaseName, namespace)
return result
}
}
msg := "Install filed" + releaseName + "in" + namespace
result.Code = 500
result.Msg = msg
return result
}
// http
func PipeHook(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
fmt.Println("method:", r.Method)
body, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Printf("read body err, %v\n", err)
return
}
tmp := string(body)
var struct_tmp PipeParams
err = json.Unmarshal([]byte(tmp), &struct_tmp)
if err != nil {
fmt.Println(err)
} else {
// fmt.Println("STRUCT:", struct_tmp.Resources.Requests.Cpu)
var resMap map[string]interface{}
err := json.Unmarshal([]byte(tmp), &resMap)
if err != nil {
fmt.Println(err)
}
response := Helm_Upgrade(resMap, struct_tmp.Namespace, struct_tmp.NameOverride)
w.Header().Set("content-type", "text/json")
msg, _ := json.Marshal(response)
w.Write(msg)
}
}
func main() {
fmt.Println("The service listens on port 9090....")
http.HandleFunc("/pipeline/", PipeHook)
err := http.ListenAndServe(":9090", nil)
if err != nil {
fmt.Printf("http server failed, err:%v\n", err)
return
}
}
- client
#!/bin/bash
curl 127.0.0.1:9090/pipeline/ --connect-timeout 15 -m 20 -X POST -d '{
"namespace": "default",
"replicaCount": "1",
"image": {
"name": "image_name",
"pullPolicy": "IfNotPresent"
},
"nameOverride": "gaea-test",
"fullnameOverride": "gaea-test",
"service": {
"type": "ClusterIP",
"port": "8080"
},
"hostAliases": {
"hostAliasesSet": false,
"hostAliasesMap": ""
},
"imagePull": {
"secretsSet": true,
"secrets": "secret-harbor"
},
"envConfig": {
"configSet": true,
"config": "configmap"
},
"resources": {
"resourcesSet": false,
"requests": {
"memory": "",
"cpu": ""
},
"limits": {
"memory": "",
"cpu": ""
}
},
"affinity": {
"affinitySet": false,
"key": "",
"operator": "In",
"values": ""
},
"tolerations": {
"tolerationsSet": false,
"key": "__TOLERATIONS_KEY__",
"operator": "Equal",
"value": "__TOLERATIONS_VALUE__",
"effect": "NoSchedule"
},
"livenessProbe": {
"livenessGetSet": false,
"livenessGet": "__LIVENESS_GET__",
"livenessCommandSet": false,
"livenessCommand": "__LIVENESS_COMMAND__"
},
"command": {
"commandSet": true,
"startCommand": "['bash','./start.sh']"
},
"AnnoTations": {
"AnnoTationSet": false,
"AnnoTationExplain": ""
}
}' --header "Content-Type: application/json"