1 package uuid
2
3 import (
4 "errors"
5 "unicode"
6
7 artifactregistryAPI "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/artifactregistry/v1beta1"
8 bigqueryAPI "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/bigquery/v1beta1"
9 containerAPI "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/container/v1beta1"
10 iamAPI "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/iam/v1beta1"
11 pubsubAPI "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/pubsub/v1beta1"
12 resourceAPI "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/resourcemanager/v1beta1"
13 secretmanagerAPI "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/secretmanager/v1beta1"
14 storageAPI "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/storage/v1beta1"
15 goext "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
16 kustomizeApi "github.com/fluxcd/kustomize-controller/api/v1"
17 sourceApi "github.com/fluxcd/source-controller/api/v1"
18 "k8s.io/apimachinery/pkg/runtime/schema"
19 "sigs.k8s.io/controller-runtime/pkg/client"
20
21 bannerApi "edge-infra.dev/pkg/edge/apis/banner/v1alpha1"
22 clusterApi "edge-infra.dev/pkg/edge/apis/cluster/v1alpha1"
23 )
24
25
26 type ResourceRequirements struct {
27 GV schema.GroupVersion
28 CanStartWithDigit bool
29 MinLength int
30 MaxLength int
31 Labels bool
32 SpecialCharacters bool
33 }
34
35 var (
36
37
38
39 ErrGVKNotSupported = errors.New("provided resource group version kind not supported")
40
41
42
43 ErrVersionNotSupported = errors.New("provided resource version not supported")
44
45 resources = map[string]ResourceRequirements{
46 resourceAPI.ProjectGVK.Kind: {
47 GV: schema.GroupVersion{
48 Group: resourceAPI.ProjectGVK.Group,
49 Version: resourceAPI.ProjectGVK.Version,
50 },
51 CanStartWithDigit: false,
52 MinLength: 6,
53 MaxLength: 30,
54 SpecialCharacters: true,
55 },
56 resourceAPI.FolderGVK.Kind: {
57 GV: schema.GroupVersion{
58 Group: resourceAPI.FolderGVK.Group,
59 Version: resourceAPI.FolderGVK.Version,
60 },
61 CanStartWithDigit: false,
62 MinLength: 6,
63 MaxLength: 30,
64 SpecialCharacters: true,
65 },
66 pubsubAPI.PubSubTopicGVK.Kind: {
67 GV: schema.GroupVersion{
68 Group: pubsubAPI.PubSubTopicGVK.Group,
69 Version: pubsubAPI.PubSubTopicGVK.Version,
70 },
71 CanStartWithDigit: false,
72 MinLength: 3,
73 MaxLength: 255,
74 SpecialCharacters: true,
75 },
76 pubsubAPI.PubSubSubscriptionGVK.Kind: {
77 GV: schema.GroupVersion{
78 Group: pubsubAPI.PubSubSubscriptionGVK.Group,
79 Version: pubsubAPI.PubSubSubscriptionGVK.Version,
80 },
81 CanStartWithDigit: false,
82 MinLength: 3,
83 MaxLength: 255,
84 SpecialCharacters: true,
85 },
86 storageAPI.StorageBucketGVK.Kind: {
87 GV: schema.GroupVersion{
88 Group: storageAPI.StorageBucketGVK.Group,
89 Version: storageAPI.StorageBucketGVK.Version,
90 },
91 CanStartWithDigit: true,
92 MinLength: 3,
93 MaxLength: 63,
94 SpecialCharacters: true,
95 },
96 containerAPI.ContainerClusterGVK.Kind: {
97 GV: schema.GroupVersion{
98 Group: containerAPI.ContainerClusterGVK.Group,
99 Version: containerAPI.ContainerClusterGVK.Version,
100 },
101 CanStartWithDigit: false,
102 MinLength: 3,
103 MaxLength: 39,
104 SpecialCharacters: true,
105 },
106 containerAPI.ContainerNodePoolGVK.Kind: {
107 GV: schema.GroupVersion{
108 Group: containerAPI.ContainerNodePoolGVK.Group,
109 Version: containerAPI.ContainerNodePoolGVK.Version,
110 },
111 CanStartWithDigit: false,
112 MinLength: 3,
113 MaxLength: 39,
114 SpecialCharacters: true,
115 },
116 secretmanagerAPI.SecretManagerSecretGVK.Kind: {
117 GV: schema.GroupVersion{
118 Group: secretmanagerAPI.SecretManagerSecretGVK.Group,
119 Version: secretmanagerAPI.SecretManagerSecretGVK.Version,
120 },
121 CanStartWithDigit: true,
122 MinLength: 3,
123 MaxLength: 255,
124 SpecialCharacters: true,
125 },
126 iamAPI.IAMServiceAccountGVK.Kind: {
127 GV: schema.GroupVersion{
128 Group: iamAPI.IAMServiceAccountGVK.Group,
129 Version: iamAPI.IAMServiceAccountGVK.Version,
130 },
131 CanStartWithDigit: true,
132 MinLength: 6,
133 MaxLength: 30,
134 SpecialCharacters: true,
135 },
136 bigqueryAPI.BigQueryTableGVK.Kind: {
137 GV: schema.GroupVersion{
138 Group: bigqueryAPI.BigQueryTableGVK.Group,
139 Version: bigqueryAPI.BigQueryTableGVK.Version,
140 },
141 CanStartWithDigit: true,
142 MinLength: 3,
143 MaxLength: 1024,
144 SpecialCharacters: true,
145 },
146 bigqueryAPI.BigQueryDatasetGVK.Kind: {
147 GV: schema.GroupVersion{
148 Group: bigqueryAPI.BigQueryDatasetGVK.Group,
149 Version: bigqueryAPI.BigQueryDatasetGVK.Version,
150 },
151 CanStartWithDigit: true,
152 MinLength: 3,
153 MaxLength: 1024,
154 SpecialCharacters: false,
155 },
156 artifactregistryAPI.ArtifactRegistryRepositoryGVK.Kind: {
157 GV: schema.GroupVersion{
158 Group: artifactregistryAPI.ArtifactRegistryRepositoryGVK.Group,
159 Version: artifactregistryAPI.ArtifactRegistryRepositoryGVK.Version,
160 },
161 CanStartWithDigit: false,
162 MinLength: 1,
163 MaxLength: 63,
164 SpecialCharacters: false,
165 },
166 iamAPI.IAMCustomRoleGVK.Kind: {
167 GV: schema.GroupVersion{
168 Group: iamAPI.IAMCustomRoleGVK.Group,
169 Version: iamAPI.IAMCustomRoleGVK.Version,
170 },
171 CanStartWithDigit: true,
172 MinLength: 1,
173 MaxLength: 100,
174 SpecialCharacters: false,
175 },
176 goext.ExtSecretGroupVersionKind.Kind: {
177 GV: schema.GroupVersion{
178 Group: goext.ExtSecretGroupVersionKind.Group,
179 Version: goext.ExtSecretGroupVersionKind.Version,
180 },
181 CanStartWithDigit: true,
182 MinLength: 1,
183 MaxLength: 100,
184 SpecialCharacters: false,
185 },
186 goext.ClusterExtSecretGroupVersionKind.Kind: {
187 GV: schema.GroupVersion{
188 Group: goext.ClusterExtSecretGroupVersionKind.Group,
189 Version: goext.ClusterExtSecretGroupVersionKind.Version,
190 },
191 CanStartWithDigit: true,
192 MinLength: 1,
193 MaxLength: 100,
194 SpecialCharacters: false,
195 },
196 kustomizeApi.KustomizationKind: {
197 GV: schema.GroupVersion{
198 Group: kustomizeApi.GroupVersion.Group,
199 Version: kustomizeApi.GroupVersion.Version,
200 },
201 CanStartWithDigit: true,
202 MinLength: 1,
203 MaxLength: 100,
204 SpecialCharacters: false,
205 },
206 sourceApi.BucketKind: {
207 GV: schema.GroupVersion{
208 Group: sourceApi.GroupVersion.Group,
209 Version: sourceApi.GroupVersion.Version,
210 },
211 CanStartWithDigit: true,
212 MinLength: 1,
213 MaxLength: 100,
214 SpecialCharacters: false,
215 },
216 sourceApi.GitRepositoryKind: {
217 GV: schema.GroupVersion{
218 Group: sourceApi.GroupVersion.Group,
219 Version: sourceApi.GroupVersion.Version,
220 },
221 CanStartWithDigit: true,
222 MinLength: 1,
223 MaxLength: 100,
224 SpecialCharacters: false,
225 },
226 sourceApi.HelmRepositoryKind: {
227 GV: schema.GroupVersion{
228 Group: sourceApi.GroupVersion.Group,
229 Version: sourceApi.GroupVersion.Version,
230 },
231 CanStartWithDigit: true,
232 MinLength: 1,
233 MaxLength: 100,
234 SpecialCharacters: false,
235 },
236 sourceApi.HelmChartKind: {
237 GV: schema.GroupVersion{
238 Group: sourceApi.GroupVersion.Group,
239 Version: sourceApi.GroupVersion.Version,
240 },
241 CanStartWithDigit: true,
242 MinLength: 1,
243 MaxLength: 100,
244 SpecialCharacters: false,
245 },
246 bannerApi.BannerKind: {
247 GV: schema.GroupVersion{
248 Group: bannerApi.GroupVersion.Group,
249 Version: bannerApi.GroupVersion.Version,
250 },
251 CanStartWithDigit: true,
252 MinLength: 1,
253 MaxLength: 100,
254 SpecialCharacters: false,
255 },
256 clusterApi.ClusterKind: {
257 GV: schema.GroupVersion{
258 Group: bannerApi.GroupVersion.Group,
259 Version: bannerApi.GroupVersion.Version,
260 },
261 CanStartWithDigit: true,
262 MinLength: 1,
263 MaxLength: 100,
264 SpecialCharacters: false,
265 },
266 }
267 )
268
269
270 func CanUseUUID(gvk schema.GroupVersionKind) (bool, error) {
271 v, k := gvk.ToAPIVersionAndKind()
272 if val, exists := resources[k]; exists {
273 switch val.GV.String() {
274 case v:
275 if val.MaxLength >= 36 && val.CanStartWithDigit {
276 return true, nil
277 }
278 return false, nil
279 default:
280 return false, ErrVersionNotSupported
281 }
282 }
283 return false, ErrGVKNotSupported
284 }
285
286
287 func CanUseHash(gvk schema.GroupVersionKind) (bool, error) {
288 v, k := gvk.ToAPIVersionAndKind()
289 if val, exists := resources[k]; exists {
290 switch val.GV.String() {
291 case v:
292 if val.MaxLength >= 12 && val.CanStartWithDigit && val.SpecialCharacters {
293 return true, nil
294 }
295 return false, nil
296 default:
297 return false, ErrVersionNotSupported
298 }
299 }
300 return false, ErrGVKNotSupported
301 }
302
303 func SatisfiesRequirement(obj client.Object) (bool, error) {
304 return satisfiesRequirement(obj)
305 }
306
307 func satisfiesRequirement(obj client.Object) (bool, error) {
308 name := obj.GetName()
309 firstCharOfName := []rune(name[0:1])
310 gvk := obj.GetObjectKind().GroupVersionKind()
311 v, k := gvk.ToAPIVersionAndKind()
312 if val, exists := resources[k]; exists {
313 switch val.GV.String() {
314 case v:
315 return len(name) <= val.MaxLength && len(name) >= val.MinLength && (unicode.IsDigit(firstCharOfName[0]) && val.CanStartWithDigit), nil
316 default:
317 return false, ErrVersionNotSupported
318 }
319 }
320 return false, ErrGVKNotSupported
321 }
322
View as plain text