Skip to content

Commit 8398916

Browse files
committed
[op] implement resourceCreateOp
1 parent af7ad9c commit 8398916

File tree

3 files changed

+220
-3
lines changed

3 files changed

+220
-3
lines changed

op/resource.go

Lines changed: 210 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,221 @@
11
package op
22

3-
import "github.com/cybozu-go/cke"
3+
import (
4+
"context"
5+
"encoding/json"
6+
"strconv"
7+
8+
"github.com/cybozu-go/cke"
9+
"github.com/cybozu-go/log"
10+
appsv1 "k8s.io/api/apps/v1"
11+
batchv2alpha1 "k8s.io/api/batch/v2alpha1"
12+
corev1 "k8s.io/api/core/v1"
13+
networkingv1 "k8s.io/api/networking/v1"
14+
policyv1beta1 "k8s.io/api/policy/v1beta1"
15+
rbacv1 "k8s.io/api/rbac/v1"
16+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
17+
)
18+
19+
type resourceCreateOp struct {
20+
apiserver *cke.Node
21+
resource cke.ResourceDefinition
22+
finished bool
23+
}
424

525
// ResourceCreateOp creates a new resource.
626
func ResourceCreateOp(apiServer *cke.Node, resource cke.ResourceDefinition) cke.Operator {
27+
return &resourceCreateOp{
28+
apiserver: apiServer,
29+
resource: resource,
30+
}
31+
}
32+
33+
func (o *resourceCreateOp) Name() string {
34+
return "resource-create"
35+
}
36+
37+
func (o *resourceCreateOp) NextCommand() cke.Commander {
38+
if o.finished {
39+
return nil
40+
}
41+
o.finished = true
42+
return o
43+
}
44+
45+
func (o *resourceCreateOp) Run(ctx context.Context, inf cke.Infrastructure) error {
46+
cs, err := inf.K8sClient(ctx, o.apiserver)
47+
if err != nil {
48+
return err
49+
}
50+
51+
switch o.resource.Kind {
52+
case "Namespace":
53+
var obj corev1.Namespace
54+
err := json.Unmarshal(o.resource.Definition, &obj)
55+
if err != nil {
56+
return err
57+
}
58+
setAnnotations(&obj.ObjectMeta, o.resource)
59+
_, err = cs.CoreV1().Namespaces().Create(&obj)
60+
if err != nil {
61+
return err
62+
}
63+
case "ServiceAccount":
64+
var obj corev1.ServiceAccount
65+
err := json.Unmarshal(o.resource.Definition, &obj)
66+
if err != nil {
67+
return err
68+
}
69+
setAnnotations(&obj.ObjectMeta, o.resource)
70+
_, err = cs.CoreV1().ServiceAccounts(o.resource.Namespace).Create(&obj)
71+
if err != nil {
72+
return err
73+
}
74+
case "ConfigMap":
75+
var obj corev1.ConfigMap
76+
err := json.Unmarshal(o.resource.Definition, &obj)
77+
if err != nil {
78+
return err
79+
}
80+
setAnnotations(&obj.ObjectMeta, o.resource)
81+
_, err = cs.CoreV1().ConfigMaps(o.resource.Namespace).Create(&obj)
82+
if err != nil {
83+
return err
84+
}
85+
case "Service":
86+
var obj corev1.Service
87+
err := json.Unmarshal(o.resource.Definition, &obj)
88+
if err != nil {
89+
return err
90+
}
91+
setAnnotations(&obj.ObjectMeta, o.resource)
92+
_, err = cs.CoreV1().Services(o.resource.Namespace).Create(&obj)
93+
if err != nil {
94+
return err
95+
}
96+
case "PodSecurityPolicy":
97+
var obj policyv1beta1.PodSecurityPolicy
98+
err := json.Unmarshal(o.resource.Definition, &obj)
99+
if err != nil {
100+
return err
101+
}
102+
setAnnotations(&obj.ObjectMeta, o.resource)
103+
_, err = cs.PolicyV1beta1().PodSecurityPolicies().Create(&obj)
104+
if err != nil {
105+
return err
106+
}
107+
case "NetworkPolicy":
108+
var obj networkingv1.NetworkPolicy
109+
err := json.Unmarshal(o.resource.Definition, &obj)
110+
if err != nil {
111+
return err
112+
}
113+
setAnnotations(&obj.ObjectMeta, o.resource)
114+
_, err = cs.NetworkingV1().NetworkPolicies(o.resource.Namespace).Create(&obj)
115+
if err != nil {
116+
return err
117+
}
118+
case "Role":
119+
var obj rbacv1.Role
120+
err := json.Unmarshal(o.resource.Definition, &obj)
121+
if err != nil {
122+
return err
123+
}
124+
setAnnotations(&obj.ObjectMeta, o.resource)
125+
_, err = cs.RbacV1().Roles(o.resource.Namespace).Create(&obj)
126+
if err != nil {
127+
return err
128+
}
129+
case "RoleBinding":
130+
var obj rbacv1.RoleBinding
131+
err := json.Unmarshal(o.resource.Definition, &obj)
132+
if err != nil {
133+
return err
134+
}
135+
setAnnotations(&obj.ObjectMeta, o.resource)
136+
_, err = cs.RbacV1().RoleBindings(o.resource.Namespace).Create(&obj)
137+
if err != nil {
138+
return err
139+
}
140+
case "ClusterRole":
141+
var obj rbacv1.ClusterRole
142+
err := json.Unmarshal(o.resource.Definition, &obj)
143+
if err != nil {
144+
return err
145+
}
146+
setAnnotations(&obj.ObjectMeta, o.resource)
147+
_, err = cs.RbacV1().ClusterRoles().Create(&obj)
148+
if err != nil {
149+
return err
150+
}
151+
case "ClusterRoleBinding":
152+
var obj rbacv1.ClusterRoleBinding
153+
err := json.Unmarshal(o.resource.Definition, &obj)
154+
if err != nil {
155+
return err
156+
}
157+
setAnnotations(&obj.ObjectMeta, o.resource)
158+
_, err = cs.RbacV1().ClusterRoleBindings().Create(&obj)
159+
if err != nil {
160+
return err
161+
}
162+
case "Deployment":
163+
var obj appsv1.Deployment
164+
err := json.Unmarshal(o.resource.Definition, &obj)
165+
if err != nil {
166+
return err
167+
}
168+
setAnnotations(&obj.ObjectMeta, o.resource)
169+
_, err = cs.AppsV1().Deployments(o.resource.Namespace).Create(&obj)
170+
if err != nil {
171+
return err
172+
}
173+
case "DaemonSet":
174+
var obj appsv1.DaemonSet
175+
err := json.Unmarshal(o.resource.Definition, &obj)
176+
if err != nil {
177+
return err
178+
}
179+
setAnnotations(&obj.ObjectMeta, o.resource)
180+
_, err = cs.AppsV1().DaemonSets(o.resource.Namespace).Create(&obj)
181+
if err != nil {
182+
return err
183+
}
184+
case "CronJob":
185+
var obj batchv2alpha1.CronJob
186+
err := json.Unmarshal(o.resource.Definition, &obj)
187+
if err != nil {
188+
return err
189+
}
190+
setAnnotations(&obj.ObjectMeta, o.resource)
191+
_, err = cs.BatchV2alpha1().CronJobs(o.resource.Namespace).Create(&obj)
192+
if err != nil {
193+
return err
194+
}
195+
default:
196+
log.Warn("unknown resource kind", map[string]interface{}{
197+
"kind": o.resource.Kind,
198+
})
199+
}
200+
7201
return nil
8202
}
9203

204+
func setAnnotations(meta *metav1.ObjectMeta, resource cke.ResourceDefinition) {
205+
if meta.Annotations == nil {
206+
meta.Annotations = make(map[string]string)
207+
}
208+
meta.Annotations[cke.AnnotationResourceRevision] = strconv.FormatInt(resource.Revision, 10)
209+
meta.Annotations[cke.AnnotationResourceOriginal] = string(resource.Definition)
210+
}
211+
212+
func (o *resourceCreateOp) Command() cke.Command {
213+
return cke.Command{
214+
Name: "create-resource",
215+
Target: o.resource.String(),
216+
}
217+
}
218+
10219
// ResourcePatchOp patches a resource using 3-way strategic merge patch.
11220
func ResourcePatchOp(apiServer *cke.Node, resource cke.ResourceDefinition) cke.Operator {
12221
return nil

storage.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ func (s Storage) GetAllResources(ctx context.Context) (map[string]ResourceDefini
466466
Namespace: namespace,
467467
Name: name,
468468
Revision: kv.ModRevision,
469-
Definition: string(kv.Value),
469+
Definition: kv.Value,
470470
}
471471
}
472472

user_resource.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,13 @@ type ResourceDefinition struct {
7878
Namespace string
7979
Name string
8080
Revision int64
81-
Definition string
81+
Definition []byte
82+
}
83+
84+
// String implements fmt.Stringer.
85+
func (d ResourceDefinition) String() string {
86+
if len(d.Namespace) == 0 {
87+
return fmt.Sprintf("%s/%s@%d", d.Kind, d.Name, d.Revision)
88+
}
89+
return fmt.Sprintf("%s/%s/%s@%d", d.Kind, d.Namespace, d.Name, d.Revision)
8290
}

0 commit comments

Comments
 (0)