1 package bannerctl
2
3 import (
4 "fmt"
5 "strings"
6
7 bannerAPI "edge-infra.dev/pkg/edge/apis/banner/v1alpha1"
8 "edge-infra.dev/pkg/k8s/konfigkonnector/apis/meta"
9 "edge-infra.dev/pkg/lib/gcp/iam"
10 "edge-infra.dev/pkg/lib/gcp/iam/roles"
11
12 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/iam/v1beta1"
13 k8sAPI "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/k8s/v1alpha1"
14 resourceAPI "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/resourcemanager/v1beta1"
15 storageAPI "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/storage/v1beta1"
16
17 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
18
19 "sigs.k8s.io/controller-runtime/pkg/client"
20 )
21
22 const (
23 kccOperatorName = "cnrm-controller-manager"
24 kccNamespace = "cnrm-system"
25 rolesFormat = "api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])"
26 siemPolicy = "storage-siemwriter"
27 siemBucket = "siem"
28 )
29
30 var (
31 KccDelegatedRoles = []string{roles.LogWriter}
32 KccDelegatedRolesExpression = fmt.Sprintf(rolesFormat, "'"+strings.Join(KccDelegatedRoles, "', '")+"'")
33 )
34
35 func (r *BannerReconciler) createClusterInfraKCCResources(b *bannerAPI.Banner, kccResourceName string, projectNumber string) []client.Object {
36 var objs []client.Object
37
38 objs = append(objs, r.createKCCIAMSA(b, kccResourceName))
39 for _, obj := range r.createKCCIAMMembers(b, kccResourceName, projectNumber) {
40 objs = append(objs, obj)
41 }
42 return objs
43 }
44
45 func (r *BannerReconciler) createKCCIAMSA(b *bannerAPI.Banner, kccResourceName string) *v1beta1.IAMServiceAccount {
46 kccSaDisplayName := fmt.Sprintf("k8s cfg connector for project %s", b.Spec.DisplayName)
47
48 return &v1beta1.IAMServiceAccount{
49 TypeMeta: gvkToTypeMeta(v1beta1.IAMServiceAccountGVK),
50 ObjectMeta: metav1.ObjectMeta{
51 Name: kccResourceName,
52 Namespace: b.Name,
53 Annotations: map[string]string{
54 meta.DeletionPolicyAnnotation: meta.DeletionPolicyAbandon,
55 },
56 OwnerReferences: r.ownerRef(b),
57 },
58
59 Spec: v1beta1.IAMServiceAccountSpec{
60 DisplayName: &kccSaDisplayName,
61 },
62 }
63 }
64
65 func (r *BannerReconciler) createKCCIAMMembers(b *bannerAPI.Banner, kccResourceName string, projectNumber string) []*v1beta1.IAMPolicyMember {
66 policyMember := iam.StandardSvcAccountMember(kccResourceName, b.Spec.GCP.ProjectID)
67 memberGVK := gvkToTypeMeta(v1beta1.IAMPolicyMemberGVK)
68
69 projectOwner := &v1beta1.IAMPolicyMember{
70 TypeMeta: memberGVK,
71 ObjectMeta: metav1.ObjectMeta{
72 Name: fmt.Sprintf("%s-owner", kccResourceName),
73 Namespace: b.Name,
74 Annotations: map[string]string{
75 meta.DeletionPolicyAnnotation: meta.DeletionPolicyAbandon,
76 },
77 OwnerReferences: r.ownerRef(b),
78 },
79 Spec: v1beta1.IAMPolicyMemberSpec{
80 Member: &policyMember,
81 ResourceRef: k8sAPI.IAMResourceRef{
82 APIVersion: resourceAPI.SchemeGroupVersion.String(),
83 Kind: resourceAPI.ProjectGVK.Kind,
84 External: b.Spec.GCP.ProjectID,
85 },
86 Role: roles.Owner,
87 },
88 }
89
90 policyName := fmt.Sprintf("%s-logging-logwriter", kccResourceName)
91 description := "KCC delegated roles on foreman"
92 delegatedRoles := &v1beta1.IAMPolicyMember{
93 TypeMeta: memberGVK,
94 ObjectMeta: metav1.ObjectMeta{
95 Name: policyName,
96 Namespace: b.Name,
97 Annotations: map[string]string{
98 meta.DeletionPolicyAnnotation: meta.DeletionPolicyAbandon,
99 },
100 OwnerReferences: r.ownerRef(b),
101 },
102 Spec: v1beta1.IAMPolicyMemberSpec{
103 Member: &policyMember,
104 ResourceRef: k8sAPI.IAMResourceRef{
105 APIVersion: resourceAPI.SchemeGroupVersion.String(),
106 Kind: resourceAPI.ProjectGVK.Kind,
107 External: r.ForemanProjectID,
108 },
109 Role: roles.ProjectAdmin,
110 Condition: &v1beta1.PolicymemberCondition{
111 Title: "kcc_delegated_foreman_roles",
112 Description: &description,
113 Expression: KccDelegatedRolesExpression,
114 },
115 },
116 }
117
118 policyName = fmt.Sprintf("%s-pubsub-admin", kccResourceName)
119 pubSubAdmin := &v1beta1.IAMPolicyMember{
120 TypeMeta: memberGVK,
121 ObjectMeta: metav1.ObjectMeta{
122 Name: policyName,
123 Namespace: b.Name,
124 Annotations: map[string]string{
125 meta.DeletionPolicyAnnotation: meta.DeletionPolicyAbandon,
126 },
127 OwnerReferences: r.ownerRef(b),
128 },
129 Spec: v1beta1.IAMPolicyMemberSpec{
130 Member: &policyMember,
131 ResourceRef: k8sAPI.IAMResourceRef{
132 APIVersion: resourceAPI.SchemeGroupVersion.String(),
133 Kind: resourceAPI.ProjectGVK.Kind,
134 External: r.ForemanProjectID,
135 },
136 Role: roles.PubsubAdmin,
137 },
138 }
139
140 wiMember := iam.WorkloadIdentityMember(b.Spec.GCP.ProjectID, kccNamespace, kccOperatorName)
141 wiUser := &v1beta1.IAMPolicyMember{
142 TypeMeta: memberGVK,
143 ObjectMeta: metav1.ObjectMeta{
144 Name: fmt.Sprintf("%s-workload-id", kccResourceName),
145 Namespace: b.Name,
146 Annotations: map[string]string{
147 meta.DeletionPolicyAnnotation: meta.DeletionPolicyAbandon,
148 },
149 OwnerReferences: r.ownerRef(b),
150 },
151 Spec: v1beta1.IAMPolicyMemberSpec{
152 Member: &wiMember,
153 ResourceRef: k8sAPI.IAMResourceRef{
154 APIVersion: v1beta1.SchemeGroupVersion.String(),
155 Kind: v1beta1.IAMServiceAccountGVK.Kind,
156 Name: kccResourceName,
157 },
158 Role: roles.WorkloadIdentityUser,
159 },
160 }
161
162 loggingPolicyMember := iam.LoggingServiceAccountMember(projectNumber)
163 siemPolicyName := fmt.Sprintf("%s-%s", kccResourceName, siemPolicy)
164 siemSinkWriter := &v1beta1.IAMPolicyMember{
165 TypeMeta: memberGVK,
166 ObjectMeta: metav1.ObjectMeta{
167 Name: siemPolicyName,
168 Namespace: b.Name,
169 Annotations: map[string]string{
170 meta.DeletionPolicyAnnotation: meta.DeletionPolicyAbandon,
171 },
172 OwnerReferences: r.ownerRef(b),
173 },
174 Spec: v1beta1.IAMPolicyMemberSpec{
175 Member: &loggingPolicyMember,
176 ResourceRef: k8sAPI.IAMResourceRef{
177 APIVersion: storageAPI.SchemeGroupVersion.String(),
178 Kind: storageAPI.StorageBucketGVK.Kind,
179 External: fmt.Sprintf("%s-%s", r.ForemanProjectID, siemBucket),
180 },
181 Role: roles.StorageObjectCreator,
182 },
183 }
184
185 return []*v1beta1.IAMPolicyMember{projectOwner, delegatedRoles, pubSubAdmin, wiUser, siemSinkWriter}
186 }
187
View as plain text