sigs.k8s.io/cluster-api@v1.7.1/cmd/clusterctl/client/repository/metadata_client.go (about)

     1  /*
     2  Copyright 2019 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  	"k8s.io/apimachinery/pkg/runtime"
    24  	"k8s.io/apimachinery/pkg/runtime/serializer"
    25  
    26  	clusterctlv1 "sigs.k8s.io/cluster-api/cmd/clusterctl/api/v1alpha3"
    27  	"sigs.k8s.io/cluster-api/cmd/clusterctl/client/config"
    28  	"sigs.k8s.io/cluster-api/cmd/clusterctl/internal/scheme"
    29  	logf "sigs.k8s.io/cluster-api/cmd/clusterctl/log"
    30  )
    31  
    32  const metadataFile = "metadata.yaml"
    33  
    34  // MetadataClient has methods to work with metadata hosted on a provider repository.
    35  // Metadata are yaml files providing additional information about provider's assets like e.g the version compatibility Matrix.
    36  type MetadataClient interface {
    37  	// Get returns the provider's metadata.
    38  	Get(ctx context.Context) (*clusterctlv1.Metadata, error)
    39  }
    40  
    41  // metadataClient implements MetadataClient.
    42  type metadataClient struct {
    43  	configVarClient config.VariablesClient
    44  	provider        config.Provider
    45  	version         string
    46  	repository      Repository
    47  }
    48  
    49  // ensure metadataClient implements MetadataClient.
    50  var _ MetadataClient = &metadataClient{}
    51  
    52  // newMetadataClient returns a metadataClient.
    53  func newMetadataClient(provider config.Provider, version string, repository Repository, config config.VariablesClient) *metadataClient {
    54  	return &metadataClient{
    55  		configVarClient: config,
    56  		provider:        provider,
    57  		version:         version,
    58  		repository:      repository,
    59  	}
    60  }
    61  
    62  func (f *metadataClient) Get(ctx context.Context) (*clusterctlv1.Metadata, error) {
    63  	log := logf.Log
    64  
    65  	// gets the metadata file from the repository
    66  	version := f.version
    67  
    68  	file, err := getLocalOverride(&newOverrideInput{
    69  		configVariablesClient: f.configVarClient,
    70  		provider:              f.provider,
    71  		version:               version,
    72  		filePath:              metadataFile,
    73  	})
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  	if file == nil {
    78  		log.V(5).Info("Fetching", "File", metadataFile, "Provider", f.provider.Name(), "Type", f.provider.Type(), "Version", version)
    79  		file, err = f.repository.GetFile(ctx, version, metadataFile)
    80  		if err != nil {
    81  			return nil, errors.Wrapf(err, "failed to read %q from the repository for provider %q", metadataFile, f.provider.ManifestLabel())
    82  		}
    83  	} else {
    84  		log.V(1).Info("Using", "Override", metadataFile, "Provider", f.provider.ManifestLabel(), "Version", version)
    85  	}
    86  
    87  	// Convert the yaml into a typed object
    88  	obj := &clusterctlv1.Metadata{}
    89  	codecFactory := serializer.NewCodecFactory(scheme.Scheme)
    90  
    91  	if err := runtime.DecodeInto(codecFactory.UniversalDecoder(), file, obj); err != nil {
    92  		return nil, errors.Wrapf(err, "error decoding %q for provider %q", metadataFile, f.provider.ManifestLabel())
    93  	}
    94  
    95  	//TODO: consider if to add metadata validation (TBD)
    96  
    97  	return obj, nil
    98  }