Merge "[#11] Implement selector kustomize primitive"
This commit is contained in:
commit
7f06e556a4
@ -2,7 +2,6 @@ package initinfra
|
||||
|
||||
import (
|
||||
"sigs.k8s.io/kustomize/v3/pkg/fs"
|
||||
"sigs.k8s.io/kustomize/v3/pkg/types"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/config"
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
@ -71,15 +70,19 @@ func (infra *Infra) Deploy() error {
|
||||
return err
|
||||
}
|
||||
|
||||
filterSelector := types.Selector{
|
||||
LabelSelector: document.EphemeralClusterSelector,
|
||||
}
|
||||
ls := document.EphemeralClusterSelector
|
||||
selector := document.NewSelector().ByLabel(ls)
|
||||
|
||||
// Get documents that are annotated to belong to initinfra
|
||||
docs, err := b.Select(filterSelector)
|
||||
docs, err := b.Select(selector)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(docs) == 0 {
|
||||
return document.ErrDocNotFound{
|
||||
Selector: ls,
|
||||
}
|
||||
}
|
||||
|
||||
// Label every document indicating that it was deployed by initinfra module for further reference
|
||||
// This may be used later to get all resources that are part of initinfra module, for monitoring, alerting
|
||||
|
@ -8,13 +8,11 @@ import (
|
||||
"sigs.k8s.io/kustomize/v3/k8sdeps/transformer"
|
||||
"sigs.k8s.io/kustomize/v3/k8sdeps/validator"
|
||||
"sigs.k8s.io/kustomize/v3/pkg/fs"
|
||||
"sigs.k8s.io/kustomize/v3/pkg/gvk"
|
||||
"sigs.k8s.io/kustomize/v3/pkg/loader"
|
||||
"sigs.k8s.io/kustomize/v3/pkg/plugins"
|
||||
"sigs.k8s.io/kustomize/v3/pkg/resmap"
|
||||
"sigs.k8s.io/kustomize/v3/pkg/resource"
|
||||
"sigs.k8s.io/kustomize/v3/pkg/target"
|
||||
"sigs.k8s.io/kustomize/v3/pkg/types"
|
||||
|
||||
docplugins "opendev.org/airship/airshipctl/pkg/document/plugins"
|
||||
"opendev.org/airship/airshipctl/pkg/log"
|
||||
@ -51,11 +49,11 @@ type Bundle interface {
|
||||
SetKustomizeBuildOptions(KustomizeBuildOptions) error
|
||||
SetFileSystem(fs.FileSystem) error
|
||||
GetFileSystem() fs.FileSystem
|
||||
Select(selector types.Selector) ([]Document, error)
|
||||
Select(selector Selector) ([]Document, error)
|
||||
GetByGvk(string, string, string) ([]Document, error)
|
||||
GetByName(string) (Document, error)
|
||||
GetByAnnotation(string) ([]Document, error)
|
||||
GetByLabel(string) ([]Document, error)
|
||||
GetByAnnotation(annotationSelector string) ([]Document, error)
|
||||
GetByLabel(labelSelector string) ([]Document, error)
|
||||
GetAllDocuments() ([]Document, error)
|
||||
}
|
||||
|
||||
@ -188,11 +186,11 @@ func (b *BundleFactory) GetByName(name string) (Document, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Select offers a direct interface to pass a Kustomize Selector to the bundle
|
||||
// returning Documents that match the criteria
|
||||
func (b *BundleFactory) Select(selector types.Selector) ([]Document, error) {
|
||||
// Select offers an interface to pass a Selector, built on top of kustomize Selector
|
||||
// to the bundle returning Documents that match the criteria
|
||||
func (b *BundleFactory) Select(selector Selector) ([]Document, error) {
|
||||
// use the kustomize select method
|
||||
resources, err := b.ResMap.Select(selector)
|
||||
resources, err := b.ResMap.Select(selector.Selector)
|
||||
if err != nil {
|
||||
return []Document{}, err
|
||||
}
|
||||
@ -211,19 +209,17 @@ func (b *BundleFactory) Select(selector types.Selector) ([]Document, error) {
|
||||
}
|
||||
|
||||
// GetByAnnotation is a convenience method to get documents for a particular annotation
|
||||
func (b *BundleFactory) GetByAnnotation(annotation string) ([]Document, error) {
|
||||
func (b *BundleFactory) GetByAnnotation(annotationSelector string) ([]Document, error) {
|
||||
// Construct kustomize annotation selector
|
||||
selector := types.Selector{AnnotationSelector: annotation}
|
||||
|
||||
selector := NewSelector().ByAnnotation(annotationSelector)
|
||||
// pass it to the selector
|
||||
return b.Select(selector)
|
||||
}
|
||||
|
||||
// GetByLabel is a convenience method to get documents for a particular label
|
||||
func (b *BundleFactory) GetByLabel(label string) ([]Document, error) {
|
||||
// Construct kustomize annotation selector
|
||||
selector := types.Selector{LabelSelector: label}
|
||||
|
||||
func (b *BundleFactory) GetByLabel(labelSelector string) ([]Document, error) {
|
||||
// Construct kustomize label selector
|
||||
selector := NewSelector().ByLabel(labelSelector)
|
||||
// pass it to the selector
|
||||
return b.Select(selector)
|
||||
}
|
||||
@ -231,10 +227,8 @@ func (b *BundleFactory) GetByLabel(label string) ([]Document, error) {
|
||||
// GetByGvk is a convenience method to get documents for a particular Gvk tuple
|
||||
func (b *BundleFactory) GetByGvk(group, version, kind string) ([]Document, error) {
|
||||
// Construct kustomize gvk object
|
||||
g := gvk.Gvk{Group: group, Version: version, Kind: kind}
|
||||
|
||||
selector := NewSelector().ByGvk(group, version, kind)
|
||||
// pass it to the selector
|
||||
selector := types.Selector{Gvk: g}
|
||||
return b.Select(selector)
|
||||
}
|
||||
|
||||
|
@ -6,9 +6,8 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"sigs.k8s.io/kustomize/v3/pkg/gvk"
|
||||
"sigs.k8s.io/kustomize/v3/pkg/types"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
"opendev.org/airship/airshipctl/testutil"
|
||||
)
|
||||
|
||||
@ -57,8 +56,7 @@ func TestBundleDocumentFiltering(t *testing.T) {
|
||||
// Select* tests test the Kustomize selector, which requires we build Kustomize
|
||||
// selector objects which is useful for advanced searches that
|
||||
// need to stack filters
|
||||
g := gvk.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"}
|
||||
selector := types.Selector{Gvk: g}
|
||||
selector := document.NewSelector().ByGvk("apps", "v1", "Deployment")
|
||||
docs, err := bundle.Select(selector)
|
||||
require.NoError(err, "Error trying to select resources")
|
||||
|
||||
@ -67,7 +65,7 @@ func TestBundleDocumentFiltering(t *testing.T) {
|
||||
|
||||
t.Run("SelectAnnotations", func(t *testing.T) {
|
||||
// Find documents with a particular annotation, namely airshipit.org/clustertype=ephemeral
|
||||
selector := types.Selector{AnnotationSelector: "airshipit.org/clustertype=ephemeral"}
|
||||
selector := document.NewSelector().ByAnnotation("airshipit.org/clustertype=ephemeral")
|
||||
docs, err := bundle.Select(selector)
|
||||
require.NoError(err, "Error trying to select annotated resources")
|
||||
|
||||
@ -78,12 +76,48 @@ func TestBundleDocumentFiltering(t *testing.T) {
|
||||
// Find documents with a particular label, namely app=workflow-controller
|
||||
// note how this will only find resources labeled at the top most level (metadata.labels)
|
||||
// and not spec templates with this label (spec.template.metadata.labels)
|
||||
selector := types.Selector{LabelSelector: "app=workflow-controller"}
|
||||
selector := document.NewSelector().ByLabel("app=workflow-controller")
|
||||
docs, err := bundle.Select(selector)
|
||||
require.NoError(err, "Error trying to select labeled resources")
|
||||
|
||||
assert.Len(docs, 1, "SelectLabels returned wrong number of resources")
|
||||
})
|
||||
|
||||
t.Run("SelectByLabelAndName", func(t *testing.T) {
|
||||
// Find documents with a particular label and name,
|
||||
// namely app=workflow-controller and name workflow-controller
|
||||
selector := document.NewSelector().ByName("workflow-controller").ByLabel("app=workflow-controller")
|
||||
docs, err := bundle.Select(selector)
|
||||
require.NoError(err, "Error trying to select labeled with name resources")
|
||||
|
||||
assert.Len(docs, 1, "SelectByLabelAndName returned wrong number of resources")
|
||||
})
|
||||
|
||||
t.Run("SelectByTwoLabels", func(t *testing.T) {
|
||||
// Find documents with two particular label, namely app=workflow-controller arbitrary-label=some-label
|
||||
selector := document.NewSelector().
|
||||
ByLabel("app=workflow-controller").
|
||||
ByLabel("arbitrary-label=some-label")
|
||||
docs, err := bundle.Select(selector)
|
||||
require.NoError(err, "Error trying to select by two labels")
|
||||
|
||||
assert.Len(docs, 1, "SelectByTwoLabels returned wrong number of resources")
|
||||
assert.Equal("workflow-controller", docs[0].GetName())
|
||||
})
|
||||
|
||||
t.Run("SelectByTwoAnnotations", func(t *testing.T) {
|
||||
// Find documents with two particular annotations,
|
||||
// namely app=workflow-controller and name workflow-controller
|
||||
selector := document.NewSelector().
|
||||
ByAnnotation("airshipit.org/clustertype=target").
|
||||
ByAnnotation("airshipit.org/random-payload=random")
|
||||
docs, err := bundle.Select(selector)
|
||||
require.NoError(err, "Error trying to select by two annotations")
|
||||
|
||||
assert.Len(docs, 1, "SelectByTwoAnnotations returned wrong number of resources")
|
||||
assert.Equal("argo-ui", docs[0].GetName())
|
||||
})
|
||||
|
||||
t.Run("Write", func(t *testing.T) {
|
||||
// Ensure we can write out a bundle
|
||||
//
|
||||
|
53
pkg/document/selectors.go
Normal file
53
pkg/document/selectors.go
Normal file
@ -0,0 +1,53 @@
|
||||
package document
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"sigs.k8s.io/kustomize/v3/pkg/gvk"
|
||||
"sigs.k8s.io/kustomize/v3/pkg/types"
|
||||
)
|
||||
|
||||
// Selector provides abstraction layer in front of kustomize selector
|
||||
type Selector struct {
|
||||
types.Selector
|
||||
}
|
||||
|
||||
// NewSelector returns instance of Selector container
|
||||
func NewSelector() Selector {
|
||||
return Selector{}
|
||||
}
|
||||
|
||||
// Following set of functions allows to build selector object
|
||||
// by name, gvk, label selector and annotation selector
|
||||
|
||||
// ByName select by name
|
||||
func (s Selector) ByName(name string) Selector {
|
||||
s.Name = name
|
||||
return s
|
||||
}
|
||||
|
||||
// ByGvk select by gvk
|
||||
func (s Selector) ByGvk(group, version, kind string) Selector {
|
||||
s.Gvk = gvk.Gvk{Group: group, Version: version, Kind: kind}
|
||||
return s
|
||||
}
|
||||
|
||||
// ByLabel select by label selector
|
||||
func (s Selector) ByLabel(labelSelector string) Selector {
|
||||
if s.LabelSelector != "" {
|
||||
s.LabelSelector = strings.Join([]string{s.LabelSelector, labelSelector}, ",")
|
||||
} else {
|
||||
s.LabelSelector = labelSelector
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// ByAnnotation select by annotation selector.
|
||||
func (s Selector) ByAnnotation(annotationSelector string) Selector {
|
||||
if s.AnnotationSelector != "" {
|
||||
s.AnnotationSelector = strings.Join([]string{s.AnnotationSelector, annotationSelector}, ",")
|
||||
} else {
|
||||
s.AnnotationSelector = annotationSelector
|
||||
}
|
||||
return s
|
||||
}
|
2
pkg/document/testdata/argo.yaml
vendored
2
pkg/document/testdata/argo.yaml
vendored
@ -232,6 +232,7 @@ kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
airshipit.org/clustertype: target
|
||||
airshipit.org/random-payload: random
|
||||
name: argo-ui
|
||||
spec:
|
||||
selector:
|
||||
@ -266,6 +267,7 @@ metadata:
|
||||
airshipit.org/clustertype: target
|
||||
labels:
|
||||
app: workflow-controller
|
||||
arbitrary-label: some-label
|
||||
name: workflow-controller
|
||||
spec:
|
||||
selector:
|
||||
|
@ -13,8 +13,6 @@ import (
|
||||
"opendev.org/airship/airshipctl/pkg/remote/redfish"
|
||||
|
||||
"sigs.k8s.io/kustomize/v3/pkg/fs"
|
||||
"sigs.k8s.io/kustomize/v3/pkg/gvk"
|
||||
"sigs.k8s.io/kustomize/v3/pkg/types"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -89,18 +87,17 @@ func getRemoteDirectConfig(settings *environment.AirshipCTLSettings) (*config.Re
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
label := document.EphemeralClusterSelector
|
||||
filter := types.Selector{
|
||||
Gvk: gvk.FromKind(AirshipHostKind),
|
||||
LabelSelector: label,
|
||||
}
|
||||
docs, err := docBundle.Select(filter)
|
||||
ls := document.EphemeralClusterSelector
|
||||
selector := document.NewSelector().
|
||||
ByGvk("", "", AirshipHostKind).
|
||||
ByLabel(ls)
|
||||
docs, err := docBundle.Select(selector)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
if len(docs) == 0 {
|
||||
return nil, "", document.ErrDocNotFound{
|
||||
Selector: label,
|
||||
Selector: ls,
|
||||
Kind: AirshipHostKind,
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user