1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package container
16
17 import (
18 "fmt"
19
20 corekccv1alpha1 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/apis/core/v1alpha1"
21 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl"
22 dclmetadata "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl/metadata"
23 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl/schema/dclschemaloader"
24 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s"
25
26 "github.com/nasa9084/go-openapi"
27 k8sschema "k8s.io/apimachinery/pkg/runtime/schema"
28 )
29
30 func GetContainersForGVK(gvk k8sschema.GroupVersionKind, smLoader dclmetadata.ServiceMetadataLoader, schemaLoader dclschemaloader.DCLSchemaLoader) ([]corekccv1alpha1.Container, error) {
31 r, found := smLoader.GetResourceWithGVK(gvk)
32 if !found {
33 return nil, fmt.Errorf("ServiceMetadata for resource with GroupVersionKind %v not found", gvk)
34 }
35 if !r.SupportsContainerAnnotations {
36 return nil, nil
37 }
38 stv, err := dclmetadata.ToServiceTypeVersion(gvk, smLoader)
39 if err != nil {
40 return nil, fmt.Errorf("error getting DCL ServiceTypeVersion for GroupVersionKind %v: %w", gvk, err)
41 }
42 dclSchema, err := schemaLoader.GetDCLSchema(stv)
43 if err != nil {
44 return nil, fmt.Errorf("error getting the DCL Schema for GroupVersionKind %v: %w", gvk, err)
45 }
46
47
48
49
50
51 if _, ok := dclSchema.Extension["x-dcl-parent-container"]; !ok {
52 containers, err := getContainersFromHierarchicalReferencesForGVK(gvk, smLoader, schemaLoader)
53 if err != nil {
54 return nil, err
55 }
56 if len(containers) == 0 {
57 return nil, fmt.Errorf("expected resource to support containers but found none based on hierarchical references")
58 }
59 return containers, nil
60 }
61 containers, err := getContainerConfigFromDCLSchema(dclSchema)
62 if err != nil {
63 return nil, fmt.Errorf("error resolving the container config from DCL schema: %w", err)
64 }
65 return containers, nil
66 }
67
68 func getContainersFromHierarchicalReferencesForGVK(gvk k8sschema.GroupVersionKind, smLoader dclmetadata.ServiceMetadataLoader, schemaLoader dclschemaloader.DCLSchemaLoader) ([]corekccv1alpha1.Container, error) {
69 hierarchicalRefs, err := dcl.GetHierarchicalReferencesForGVK(gvk, smLoader, schemaLoader)
70 if err != nil {
71 return nil, err
72 }
73 containerTypes := k8s.ContainerTypesFor(hierarchicalRefs)
74 return containerConfigFromContainerTypes(containerTypes), nil
75 }
76
77 func getContainerConfigFromDCLSchema(schema *openapi.Schema) ([]corekccv1alpha1.Container, error) {
78 container, hasContainer, err := getContainerType(schema)
79 if err != nil {
80 return nil, err
81 }
82 if !hasContainer {
83 return nil, nil
84 }
85 containerTypes := make([]corekccv1alpha1.ContainerType, 0)
86 switch container {
87 case corekccv1alpha1.ContainerTypeProject,
88 corekccv1alpha1.ContainerTypeFolder,
89 corekccv1alpha1.ContainerTypeOrganization:
90 containerTypes = append(containerTypes, corekccv1alpha1.ContainerType(container))
91 default:
92 return nil, fmt.Errorf("invalid container type %v", container)
93 }
94 return containerConfigFromContainerTypes(containerTypes), nil
95 }
96
97 func getContainerType(schema *openapi.Schema) (string, bool, error) {
98 raw, ok := schema.Extension["x-dcl-parent-container"]
99 if !ok {
100 return "", false, nil
101 }
102
103 container, ok := raw.(string)
104 if !ok {
105 return "", false, fmt.Errorf("wrong type for 'x-dcl-parent-container' extension: %T, expect to have string type", raw)
106 }
107 return container, true, nil
108 }
109
110 func containerConfigFromContainerTypes(containerTypes []corekccv1alpha1.ContainerType) []corekccv1alpha1.Container {
111 containers := make([]corekccv1alpha1.Container, 0)
112 for _, c := range containerTypes {
113 containers = append(containers, corekccv1alpha1.Container{
114
115
116 TFField: string(c),
117 Type: c,
118 })
119 }
120 return containers
121 }
122
View as plain text