...

Source file src/github.com/GoogleCloudPlatform/k8s-config-connector/pkg/crd/template/template.go

Documentation: github.com/GoogleCloudPlatform/k8s-config-connector/pkg/crd/template

     1  // Copyright 2022 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package crdtemplate
    16  
    17  import (
    18  	"fmt"
    19  
    20  	"github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s"
    21  
    22  	"gopkg.in/yaml.v2"
    23  	apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
    24  )
    25  
    26  func SpecToYAML(crd *apiextensions.CustomResourceDefinition) ([]byte, error) {
    27  	specPropertyName := "spec"
    28  	schema := k8s.GetOpenAPIV3SchemaFromCRD(crd)
    29  	spec, ok := schema.Properties[specPropertyName]
    30  	if !ok {
    31  		// this occurs when a CRD has an empty spec, such as ComputeSharedVPCHostProject
    32  		return make([]byte, 0), nil
    33  	}
    34  	return propsToYAML(spec)
    35  }
    36  
    37  func StatusToYAML(crd *apiextensions.CustomResourceDefinition) ([]byte, error) {
    38  	statusPropertyName := "status"
    39  	schema := k8s.GetOpenAPIV3SchemaFromCRD(crd)
    40  	status, ok := schema.Properties[statusPropertyName]
    41  	if !ok {
    42  		return nil, fmt.Errorf("unexpected missing '%v' on crd '%v'", statusPropertyName, crd.Spec.Names.Kind)
    43  	}
    44  	return propsToYAML(status)
    45  }
    46  
    47  func propsToYAML(props apiextensions.JSONSchemaProps) ([]byte, error) {
    48  	value := propsToValue(props)
    49  	bytes, err := yaml.Marshal(value)
    50  	if err != nil {
    51  		return nil, fmt.Errorf("error marshalling value yaml: %v", err)
    52  	}
    53  	return bytes, nil
    54  }
    55  
    56  func propsToValue(props apiextensions.JSONSchemaProps) interface{} {
    57  	switch props.Type {
    58  	case "object":
    59  		return objectToValue(props)
    60  	case "array":
    61  		return []interface{}{propsToValue(*props.Items.Schema)}
    62  	case "boolean", "integer", "string":
    63  		return props.Type
    64  	case "number":
    65  		return "float"
    66  	default:
    67  		panic(fmt.Sprintf("unhandled type: %v", props.Type))
    68  	}
    69  }
    70  
    71  func objectToValue(props apiextensions.JSONSchemaProps) interface{} {
    72  	if isMapType(props) {
    73  		value := make(map[string]string)
    74  		value["string"] = props.AdditionalProperties.Schema.Type
    75  		return value
    76  	}
    77  	value := make(map[string]interface{}, len(props.Properties))
    78  	for k, v := range props.Properties {
    79  		value[k] = propsToValue(v)
    80  	}
    81  	return value
    82  }
    83  
    84  func isMapType(props apiextensions.JSONSchemaProps) bool {
    85  	// this property represents a user defined map
    86  	return props.AdditionalProperties != nil && props.AdditionalProperties.Allows
    87  }
    88  

View as plain text