1
16
17
18 package main
19
20 import (
21 "bufio"
22 "context"
23 "flag"
24 "fmt"
25 "os"
26 "path/filepath"
27
28 apiv1 "k8s.io/api/core/v1"
29 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
30 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
31 "k8s.io/apimachinery/pkg/runtime/schema"
32 "k8s.io/client-go/dynamic"
33 "k8s.io/client-go/tools/clientcmd"
34 "k8s.io/client-go/util/homedir"
35 "k8s.io/client-go/util/retry"
36
37
38
39
40
41
42
43
44 )
45
46 func main() {
47 var kubeconfig *string
48 if home := homedir.HomeDir(); home != "" {
49 kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
50 } else {
51 kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
52 }
53 flag.Parse()
54
55 config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
56 if err != nil {
57 panic(err)
58 }
59 client, err := dynamic.NewForConfig(config)
60 if err != nil {
61 panic(err)
62 }
63
64 deploymentRes := schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"}
65
66 deployment := &unstructured.Unstructured{
67 Object: map[string]interface{}{
68 "apiVersion": "apps/v1",
69 "kind": "Deployment",
70 "metadata": map[string]interface{}{
71 "name": "demo-deployment",
72 },
73 "spec": map[string]interface{}{
74 "replicas": 2,
75 "selector": map[string]interface{}{
76 "matchLabels": map[string]interface{}{
77 "app": "demo",
78 },
79 },
80 "template": map[string]interface{}{
81 "metadata": map[string]interface{}{
82 "labels": map[string]interface{}{
83 "app": "demo",
84 },
85 },
86
87 "spec": map[string]interface{}{
88 "containers": []map[string]interface{}{
89 {
90 "name": "web",
91 "image": "nginx:1.12",
92 "ports": []map[string]interface{}{
93 {
94 "name": "http",
95 "protocol": "TCP",
96 "containerPort": 80,
97 },
98 },
99 },
100 },
101 },
102 },
103 },
104 },
105 }
106
107
108 fmt.Println("Creating deployment...")
109 result, err := client.Resource(deploymentRes).Namespace(apiv1.NamespaceDefault).Create(context.TODO(), deployment, metav1.CreateOptions{})
110 if err != nil {
111 panic(err)
112 }
113 fmt.Printf("Created deployment %q.\n", result.GetName())
114
115
116 prompt()
117 fmt.Println("Updating deployment...")
118
119
120
121
122
123
124
125
126
127
128
129
130
131 retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
132
133
134 result, getErr := client.Resource(deploymentRes).Namespace(apiv1.NamespaceDefault).Get(context.TODO(), "demo-deployment", metav1.GetOptions{})
135 if getErr != nil {
136 panic(fmt.Errorf("failed to get latest version of Deployment: %v", getErr))
137 }
138
139
140 if err := unstructured.SetNestedField(result.Object, int64(1), "spec", "replicas"); err != nil {
141 panic(fmt.Errorf("failed to set replica value: %v", err))
142 }
143
144
145 containers, found, err := unstructured.NestedSlice(result.Object, "spec", "template", "spec", "containers")
146 if err != nil || !found || containers == nil {
147 panic(fmt.Errorf("deployment containers not found or error in spec: %v", err))
148 }
149
150
151 if err := unstructured.SetNestedField(containers[0].(map[string]interface{}), "nginx:1.13", "image"); err != nil {
152 panic(err)
153 }
154 if err := unstructured.SetNestedField(result.Object, containers, "spec", "template", "spec", "containers"); err != nil {
155 panic(err)
156 }
157
158 _, updateErr := client.Resource(deploymentRes).Namespace(apiv1.NamespaceDefault).Update(context.TODO(), result, metav1.UpdateOptions{})
159 return updateErr
160 })
161 if retryErr != nil {
162 panic(fmt.Errorf("update failed: %v", retryErr))
163 }
164 fmt.Println("Updated deployment...")
165
166
167 prompt()
168 fmt.Printf("Listing deployments in namespace %q:\n", apiv1.NamespaceDefault)
169 list, err := client.Resource(deploymentRes).Namespace(apiv1.NamespaceDefault).List(context.TODO(), metav1.ListOptions{})
170 if err != nil {
171 panic(err)
172 }
173 for _, d := range list.Items {
174 replicas, found, err := unstructured.NestedInt64(d.Object, "spec", "replicas")
175 if err != nil || !found {
176 fmt.Printf("Replicas not found for deployment %s: error=%s", d.GetName(), err)
177 continue
178 }
179 fmt.Printf(" * %s (%d replicas)\n", d.GetName(), replicas)
180 }
181
182
183 prompt()
184 fmt.Println("Deleting deployment...")
185 deletePolicy := metav1.DeletePropagationForeground
186 deleteOptions := metav1.DeleteOptions{
187 PropagationPolicy: &deletePolicy,
188 }
189 if err := client.Resource(deploymentRes).Namespace(apiv1.NamespaceDefault).Delete(context.TODO(), "demo-deployment", deleteOptions); err != nil {
190 panic(err)
191 }
192
193 fmt.Println("Deleted deployment.")
194 }
195
196 func prompt() {
197 fmt.Printf("-> Press Return key to continue.")
198 scanner := bufio.NewScanner(os.Stdin)
199 for scanner.Scan() {
200 break
201 }
202 if err := scanner.Err(); err != nil {
203 panic(err)
204 }
205 fmt.Println()
206 }
207
View as plain text