Add metadata support for clusterctl repository implementation

Change-Id: Ie9285cbba0fb590392b975be1eb2b02b28de56d1
This commit is contained in:
Kostiantyn Kalynovskyi 2020-04-28 16:21:42 -05:00
parent 009794e408
commit 1969866b0a
8 changed files with 109 additions and 20 deletions

View File

@ -12,9 +12,7 @@ import (
)
const (
// TODO Add metadata support. Clusterctl uses repository to read metadata.yaml file
// to get clusterctl metadata which is a link between provider version and api version
// that it supports, for example v0.3.0 --> v1alpha3
metaDataFilePath = "metadata.yaml"
dummyComponentPath = "components.yaml"
)
@ -57,10 +55,7 @@ func (r *Repository) RootPath() string {
}
// GetFile returns all kubernetes resources that belong to cluster-api
// TODO Add metadata support(don't ignore filepath). Clusterctl uses repository to read
// metadata.yaml file to get clusterctl metadata which is a link between provider version
// and api version that it supports, for example v0.3.0 --> v1alpha3
func (r *Repository) GetFile(version string, _ string) ([]byte, error) {
func (r *Repository) GetFile(version string, filePath string) ([]byte, error) {
if version == "latest" {
// default should be latest
version = r.defaultVersion
@ -74,10 +69,21 @@ func (r *Repository) GetFile(version string, _ string) ([]byte, error) {
if err != nil {
return nil, err
}
// TODO when clusterctl will have a defined set of expected files in repository
// revisit this implementation
// metadata.yaml should return a bytes containing clusterctlv1.Metadata or error
if filePath == metaDataFilePath {
doc, errMeta := bundle.SelectOne(document.NewClusterctlMetadataSelector())
if errMeta != nil {
return nil, errMeta
}
return doc.AsYAML()
}
filteredBundle, err := bundle.SelectBundle(document.NewDeployToK8sSelector())
if err != nil {
return nil, err
}
buffer := bytes.NewBuffer([]byte{})
err = filteredBundle.Write(buffer)
if err != nil {

View File

@ -6,6 +6,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
versionclient "k8s.io/apimachinery/pkg/util/version"
clusterctlv1 "sigs.k8s.io/cluster-api/cmd/clusterctl/api/v1alpha3"
"sigs.k8s.io/yaml"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -90,12 +92,14 @@ func TestNewRepository(t *testing.T) {
func TestGetFile(t *testing.T) {
tests := []struct {
name string
root string
versions map[string]string
expectErr bool
resultVersion string
versionToUse string
name string
root string
versions map[string]string
expectErr bool
resultVersion string
versionToUse string
fileToUse string
resultContract string
}{
{
name: "single version",
@ -149,6 +153,28 @@ func TestGetFile(t *testing.T) {
versionToUse: "v1.3.3",
expectErr: true,
},
{
name: "test valid metadata",
root: "testdata",
versions: map[string]string{
"v0.2.3": "functions/2",
},
expectErr: false,
versionToUse: "v0.2.3",
fileToUse: "metadata.yaml",
resultContract: "v1alpha2",
},
{
name: "test valid metadata",
root: "testdata",
versions: map[string]string{
"v0.2.0": "functions/1",
},
expectErr: true,
versionToUse: "v0.2.3",
fileToUse: "metadata.yaml",
resultContract: "v1alpha2",
},
}
for _, tt := range tests {
root := tt.root
@ -156,19 +182,26 @@ func TestGetFile(t *testing.T) {
resultVersion := tt.resultVersion
versionToUse := tt.versionToUse
expectErr := tt.expectErr
fileToUse := tt.fileToUse
resultContract := tt.resultContract
t.Run(tt.name, func(t *testing.T) {
repo, err := implementations.NewRepository(root, versions)
require.NoError(t, err)
assert.NoError(t, err)
assert.NotNil(t, repo)
b, err := repo.GetFile(versionToUse, "")
b, err := repo.GetFile(versionToUse, fileToUse)
if expectErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
gotVersion := version(t, b)
assert.Equal(t, resultVersion, gotVersion.Spec.Version)
if fileToUse == "metadata.yaml" {
gotMetdata := metadata(t, b)
parsedVersion, err := versionclient.ParseSemantic(versionToUse)
require.NoError(t, err)
assert.Equal(t, resultContract, gotMetdata.GetReleaseSeriesForVersion(parsedVersion).Contract)
} else {
gotVersion := version(t, b)
assert.Equal(t, resultVersion, gotVersion.Spec.Version)
}
}
})
}
@ -183,6 +216,14 @@ func version(t *testing.T, versionBytes []byte) *Version {
return ver
}
func metadata(t *testing.T, metadataBytes []byte) *clusterctlv1.Metadata {
t.Helper()
m := &clusterctlv1.Metadata{}
err := yaml.Unmarshal(metadataBytes, m)
require.NoError(t, err)
return m
}
func TestComponentsPath(t *testing.T) {
versions := map[string]string{
"v0.0.1": "functions/1",

View File

@ -5,3 +5,15 @@ metadata:
name: version-2
spec:
version: v0.0.2
---
apiVersion: clusterctl.cluster.x-k8s.io/v1alpha3
kind: Metadata
metadata:
name: repository-metadata
releaseSeries:
- major: 0
minor: 3
contract: v1alpha3
- major: 0
minor: 2
contract: v1alpha2

View File

@ -26,8 +26,12 @@ const (
DeployToK8sSelector = "airshipit.org/deploy-k8s notin (False, false)"
)
// Kinds
// GVKs
const (
SecretKind = "Secret"
BareMetalHostKind = "BareMetalHost"
ClusterctlMetadataKind = "Metadata"
ClusterctlMetadataVersion = "v1alpha3"
ClusterctlMetadataGroup = "clusterctl.cluster.x-k8s.io"
)

View File

@ -157,3 +157,10 @@ func NewNetworkDataSelector(bmhDoc Document) (Selector, error) {
func NewDeployToK8sSelector() Selector {
return NewSelector().ByLabel(DeployToK8sSelector)
}
// NewClusterctlMetadataSelector returns selector to get clusterctl metadata documents
func NewClusterctlMetadataSelector() Selector {
return NewSelector().ByGvk(ClusterctlMetadataGroup,
ClusterctlMetadataVersion,
ClusterctlMetadataKind)
}

View File

@ -48,6 +48,12 @@ func TestSelectorsPositive(t *testing.T) {
require.NoError(t, err)
assert.Len(t, doc, 1)
})
t.Run("TestNewClusterctlMetadataSelector", func(t *testing.T) {
doc, err := bundle.Select(document.NewClusterctlMetadataSelector())
require.NoError(t, err)
assert.Len(t, doc, 1)
})
}
func TestSelectorsNegative(t *testing.T) {

View File

@ -1,4 +1,5 @@
resources:
- baremetal.yaml
- secret.yaml
- argo.yaml
- argo.yaml
- metadata.yaml

View File

@ -0,0 +1,12 @@
---
apiVersion: clusterctl.cluster.x-k8s.io/v1alpha3
kind: Metadata
metadata:
name: repository-metadata
releaseSeries:
- major: 0
minor: 3
contract: v1alpha3
- major: 0
minor: 2
contract: v1alpha2