...

Source file src/github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl/mutableunreadable.go

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

     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 dcl
    16  
    17  import (
    18  	"fmt"
    19  
    20  	"github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl/extension"
    21  	"github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s"
    22  	"github.com/GoogleCloudPlatform/k8s-config-connector/pkg/util/typeutil"
    23  
    24  	"github.com/nasa9084/go-openapi"
    25  )
    26  
    27  func MutableButUnreadableFieldsAnnotationFor(r *Resource) (string, error) {
    28  	paths, err := getMutableButUnreadablePaths(r)
    29  	if err != nil {
    30  		return "", fmt.Errorf("error getting mutable-but-unreadable fields for resource: %w", err)
    31  	}
    32  	return k8s.GenerateMutableButUnreadableFieldsAnnotation(&r.Resource, paths)
    33  }
    34  
    35  // getMutableButUnreadablePaths returns the list of fields supported by the
    36  // resource that are mutable but unreadable. Each field is broken down into its
    37  // path elements (i.e. ["spec", "fooBar"] instead of "spec.fooBar").
    38  func getMutableButUnreadablePaths(r *Resource) ([][]string, error) {
    39  	paths, err := getMutableButUnreadableDCLPathsInObject([]string{}, r.Schema)
    40  	if err != nil {
    41  		return nil, fmt.Errorf("error getting mutable-but-unreadable fields from the DCL resource schema: %w", err)
    42  	}
    43  	return paths, nil
    44  }
    45  
    46  func GetMutableButUnreadableFieldsFromAnnotations(r *Resource) (map[string]interface{}, error) {
    47  	paths, err := getMutableButUnreadablePaths(r)
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  	return k8s.GetMutableButUnreadableFieldsFromAnnotations(&r.Resource, paths)
    52  }
    53  
    54  func getMutableButUnreadableDCLPathsInObject(path []string, schema *openapi.Schema) ([][]string, error) {
    55  	if schema.Type != "object" {
    56  		return nil, fmt.Errorf("expect the schema type to be 'object', but got %v", schema.Type)
    57  	}
    58  
    59  	results := make([][]string, 0)
    60  	for subField, subSchema := range schema.Properties {
    61  		subPath := append(path, subField)
    62  
    63  		// ReadOnly fields should be skipped because they and their subfields
    64  		// can't be mutable but unreadable.
    65  		if subSchema.ReadOnly {
    66  			continue
    67  		}
    68  
    69  		isMutableButUnreadable, err := extension.IsMutableButUnreadableField(subSchema)
    70  		if err != nil {
    71  			return nil, err
    72  		}
    73  		if isMutableButUnreadable {
    74  			results = append(results, subPath)
    75  			continue
    76  		}
    77  
    78  		switch subSchema.Type {
    79  		// We haven't determined whether 'x-dcl-mutable-unreadable' extension should
    80  		// be set at the field-level, or within the item schema for an array. More
    81  		// details here: http://b/186078207.
    82  		// Currently KCC is also checking the item schema within an array.
    83  		case "array":
    84  			// Mutable-but-unreadable feature is not supported for array fields
    85  			// with non-primitive types.
    86  			if !typeutil.IsPrimitiveTypeArray(subSchema.Items) {
    87  				continue
    88  			}
    89  
    90  			isMutableButUnreadable, err := extension.IsMutableButUnreadableField(subSchema.Items)
    91  			if err != nil {
    92  				return nil, err
    93  			}
    94  			if isMutableButUnreadable {
    95  				results = append(results, subPath)
    96  			}
    97  		// Object field is not a mutable-but-unreadable field, but might contain fields that are.
    98  		case "object":
    99  			subResults, err := getMutableButUnreadableDCLPathsInObject(subPath, subSchema)
   100  			if err != nil {
   101  				return nil, fmt.Errorf("error getting mutable-but-unreadable fields under sub field %s: %w\n", subField, err)
   102  			}
   103  			results = append(results, subResults...)
   104  		}
   105  	}
   106  	return results, nil
   107  }
   108  

View as plain text