sigs.k8s.io/cluster-api@v1.7.1/cmd/clusterctl/client/repository/template_client.go (about) 1 /* 2 Copyright 2020 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package repository 18 19 import ( 20 "context" 21 22 "github.com/pkg/errors" 23 24 "sigs.k8s.io/cluster-api/cmd/clusterctl/client/config" 25 yaml "sigs.k8s.io/cluster-api/cmd/clusterctl/client/yamlprocessor" 26 logf "sigs.k8s.io/cluster-api/cmd/clusterctl/log" 27 ) 28 29 // TemplateClient has methods to work with cluster templates hosted on a provider repository. 30 // Templates are yaml files to be used for creating a guest cluster. 31 type TemplateClient interface { 32 Get(ctx context.Context, flavor, targetNamespace string, listVariablesOnly bool) (Template, error) 33 } 34 35 // templateClient implements TemplateClient. 36 type templateClient struct { 37 provider config.Provider 38 version string 39 repository Repository 40 configVariablesClient config.VariablesClient 41 processor yaml.Processor 42 } 43 44 // TemplateClientInput is an input strict for newTemplateClient. 45 type TemplateClientInput struct { 46 version string 47 provider config.Provider 48 repository Repository 49 configVariablesClient config.VariablesClient 50 processor yaml.Processor 51 } 52 53 // Ensure templateClient implements the TemplateClient interface. 54 var _ TemplateClient = &templateClient{} 55 56 // newTemplateClient returns a templateClient. It uses the SimpleYamlProcessor 57 // by default. 58 func newTemplateClient(input TemplateClientInput) *templateClient { 59 return &templateClient{ 60 provider: input.provider, 61 version: input.version, 62 repository: input.repository, 63 configVariablesClient: input.configVariablesClient, 64 processor: input.processor, 65 } 66 } 67 68 // Get return the template for the flavor specified. 69 // In case the template does not exists, an error is returned. 70 // Get assumes the following naming convention for templates: cluster-template[-<flavor_name>].yaml. 71 func (c *templateClient) Get(ctx context.Context, flavor, targetNamespace string, skipTemplateProcess bool) (Template, error) { 72 log := logf.Log 73 74 if targetNamespace == "" { 75 return nil, errors.New("invalid arguments: please provide a targetNamespace") 76 } 77 78 version := c.version 79 name := c.processor.GetTemplateName(version, flavor) 80 81 // read the component YAML, reading the local override file if it exists, otherwise read from the provider repository 82 rawArtifact, err := getLocalOverride(&newOverrideInput{ 83 configVariablesClient: c.configVariablesClient, 84 provider: c.provider, 85 version: version, 86 filePath: name, 87 }) 88 if err != nil { 89 return nil, err 90 } 91 92 if rawArtifact == nil { 93 log.V(5).Info("Fetching", "File", name, "Provider", c.provider.Name(), "Type", c.provider.Type(), "Version", version) 94 rawArtifact, err = c.repository.GetFile(ctx, version, name) 95 if err != nil { 96 return nil, errors.Wrapf(err, "failed to read %q from provider's repository %q", name, c.provider.ManifestLabel()) 97 } 98 } else { 99 log.V(1).Info("Using", "Override", name, "Provider", c.provider.ManifestLabel(), "Version", version) 100 } 101 102 return NewTemplate(TemplateInput{ 103 rawArtifact, 104 c.configVariablesClient, 105 c.processor, 106 targetNamespace, 107 skipTemplateProcess, 108 }) 109 }