0ab9b6d7ea
Implementation would allow us to build our own cluster-api components based on airship document bundle. Relates-To: #170 Change-Id: Ic029fd07ca5221747e49c3cf48e80a3e279ac1f0
117 lines
3.6 KiB
Go
117 lines
3.6 KiB
Go
package implementations
|
|
|
|
import (
|
|
"bytes"
|
|
"path/filepath"
|
|
|
|
"k8s.io/apimachinery/pkg/util/version"
|
|
"sigs.k8s.io/cluster-api/cmd/clusterctl/client/repository"
|
|
|
|
"opendev.org/airship/airshipctl/pkg/document"
|
|
"opendev.org/airship/airshipctl/pkg/log"
|
|
)
|
|
|
|
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
|
|
dummyComponentPath = "components.yaml"
|
|
)
|
|
|
|
// Repository implements Repository from clusterctl project
|
|
type Repository struct {
|
|
root string
|
|
versions map[string]string
|
|
defaultVersion string
|
|
}
|
|
|
|
var _ repository.Repository = &Repository{}
|
|
|
|
// ComponentsPath always returns same value, since it is not relevant without real filesystem
|
|
func (r *Repository) ComponentsPath() string {
|
|
return dummyComponentPath
|
|
}
|
|
|
|
// GetVersions retrieve all versions from the repository
|
|
func (r *Repository) GetVersions() ([]string, error) {
|
|
versions := make([]string, 0, len(r.versions))
|
|
for availableVersion := range r.versions {
|
|
_, err := version.ParseSemantic(availableVersion)
|
|
if err != nil {
|
|
// discard releases with tags that are not a valid semantic versions (the user can point explicitly to such releases)
|
|
continue
|
|
}
|
|
versions = append(versions, availableVersion)
|
|
}
|
|
return versions, nil
|
|
}
|
|
|
|
// DefaultVersion highest version available
|
|
func (r *Repository) DefaultVersion() string {
|
|
return r.defaultVersion
|
|
}
|
|
|
|
// RootPath not relevant without real filesystem
|
|
func (r *Repository) RootPath() string {
|
|
return r.root
|
|
}
|
|
|
|
// 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) {
|
|
if version == "latest" {
|
|
// default should be latest
|
|
version = r.defaultVersion
|
|
}
|
|
path, ok := r.versions[version]
|
|
if !ok {
|
|
return nil, ErrVersionNotDefined{Version: version}
|
|
}
|
|
|
|
bundle, err := document.NewBundleByPath(filepath.Join(r.root, path))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
filteredBundle, err := bundle.SelectBundle(document.NewDeployToK8sSelector())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
buffer := bytes.NewBuffer([]byte{})
|
|
err = filteredBundle.Write(buffer)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return buffer.Bytes(), nil
|
|
}
|
|
|
|
// NewRepository builds instance of repository
|
|
func NewRepository(root string, versions map[string]string) (repository.Repository, error) {
|
|
var latestVersion *version.Version
|
|
var latestStringVersion string
|
|
// calculate latest version and delete versions that do not obey version syntax
|
|
for ver := range versions {
|
|
availableSemVersion, err := version.ParseSemantic(ver)
|
|
if err != nil {
|
|
// ignore and delete version if we can't parse it.
|
|
log.Debugf(`Invalid version %s in repository versions map %q, ignoring it. Version must obey the syntax,
|
|
semantics of the "Semantic Versioning" specification (http://semver.org/)`, ver, versions)
|
|
// delete the version so actual version list is clean
|
|
delete(versions, ver)
|
|
continue
|
|
}
|
|
if latestVersion == nil || latestVersion.LessThan(availableSemVersion) {
|
|
latestVersion = availableSemVersion
|
|
latestStringVersion = ver
|
|
}
|
|
}
|
|
if latestStringVersion == "" {
|
|
return nil, ErrNoVersionsAvailable{Versions: versions}
|
|
}
|
|
return &Repository{
|
|
root: root,
|
|
versions: versions,
|
|
defaultVersion: latestStringVersion}, nil
|
|
}
|