Merge "Create StatusMaps from current cluster state"
This commit is contained in:
commit
2cba93cbaf
@ -39,35 +39,35 @@ const (
|
|||||||
// a resource may be in, as well as the Expression used to check for that
|
// a resource may be in, as well as the Expression used to check for that
|
||||||
// status.
|
// status.
|
||||||
type StatusMap struct {
|
type StatusMap struct {
|
||||||
|
client client.Interface
|
||||||
mapping map[schema.GroupVersionResource]map[Status]Expression
|
mapping map[schema.GroupVersionResource]map[Status]Expression
|
||||||
restMapper *meta.DefaultRESTMapper
|
restMapper *meta.DefaultRESTMapper
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewStatusMap creates a StatusMap for a given document bundle. It iterates
|
// NewStatusMap creates a cluster-wide StatusMap. It iterates over all
|
||||||
// over all CustomResourceDefinitions that are annotated with the
|
// CustomResourceDefinitions in the cluster that are annotated with the
|
||||||
// airshipit.org/status-check annotation and creates a mapping from the
|
// airshipit.org/status-check annotation and creates a mapping from the
|
||||||
// GroupVersionResource to the various statuses and their associated
|
// GroupVersionResource to the various statuses and their associated
|
||||||
// expressions.
|
// expressions.
|
||||||
func NewStatusMap(docBundle document.Bundle) (*StatusMap, error) {
|
func NewStatusMap(client client.Interface) (*StatusMap, error) {
|
||||||
statusMap := &StatusMap{
|
statusMap := &StatusMap{
|
||||||
|
client: client,
|
||||||
mapping: make(map[schema.GroupVersionResource]map[Status]Expression),
|
mapping: make(map[schema.GroupVersionResource]map[Status]Expression),
|
||||||
restMapper: meta.NewDefaultRESTMapper([]schema.GroupVersion{}),
|
restMapper: meta.NewDefaultRESTMapper([]schema.GroupVersion{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
v1CRDS, err := docBundle.GetByGvk("apiextensions.k8s.io", "v1", "CustomResourceDefinition")
|
crds, err := statusMap.client.ApiextensionsClientSet().
|
||||||
|
ApiextensionsV1().
|
||||||
|
CustomResourceDefinitions().
|
||||||
|
List(metav1.ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// for legacy support
|
for _, crd := range crds.Items {
|
||||||
v1beta1CRDS, err := docBundle.GetByGvk("apiextensions.k8s.io", "v1beta1", "CustomResourceDefinition")
|
if err = statusMap.addCRD(crd); err != nil {
|
||||||
if err != nil {
|
return nil, err
|
||||||
return nil, err
|
}
|
||||||
}
|
|
||||||
|
|
||||||
crds := append(v1CRDS, v1beta1CRDS...)
|
|
||||||
if err = statusMap.addCRDs(crds); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return statusMap, nil
|
return statusMap, nil
|
||||||
@ -75,7 +75,7 @@ func NewStatusMap(docBundle document.Bundle) (*StatusMap, error) {
|
|||||||
|
|
||||||
// GetStatusForResource iterates over all of the stored conditions for the
|
// GetStatusForResource iterates over all of the stored conditions for the
|
||||||
// resource and returns the first status whose conditions are met.
|
// resource and returns the first status whose conditions are met.
|
||||||
func (sm *StatusMap) GetStatusForResource(client client.Interface, resource document.Document) (Status, error) {
|
func (sm *StatusMap) GetStatusForResource(resource document.Document) (Status, error) {
|
||||||
gvk, err := getGVK(resource)
|
gvk, err := getGVK(resource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -87,7 +87,7 @@ func (sm *StatusMap) GetStatusForResource(client client.Interface, resource docu
|
|||||||
}
|
}
|
||||||
|
|
||||||
gvr := restMapping.Resource
|
gvr := restMapping.Resource
|
||||||
obj, err := client.DynamicClient().Resource(gvr).Namespace(resource.GetNamespace()).
|
obj, err := sm.client.DynamicClient().Resource(gvr).Namespace(resource.GetNamespace()).
|
||||||
Get(resource.GetName(), metav1.GetOptions{})
|
Get(resource.GetName(), metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -109,39 +109,28 @@ func (sm *StatusMap) GetStatusForResource(client client.Interface, resource docu
|
|||||||
return UnknownStatus, nil
|
return UnknownStatus, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// addCRDs adds the mappings from each crd to their associated statuses.
|
// addCRD adds the mappings from the CRD to its associated statuses
|
||||||
func (sm *StatusMap) addCRDs(crdDocs []document.Document) error {
|
func (sm *StatusMap) addCRD(crd apiextensions.CustomResourceDefinition) error {
|
||||||
for _, crdDoc := range crdDocs {
|
annotations := crd.GetAnnotations()
|
||||||
annotations := crdDoc.GetAnnotations()
|
rawStatusChecks, ok := annotations["airshipit.org/status-check"]
|
||||||
rawStatusChecks, ok := annotations["airshipit.org/status-check"]
|
if !ok {
|
||||||
if !ok {
|
// This crd doesn't have a status-check
|
||||||
// This crdDoc doesn't have a status-check
|
// annotation, so we should skip it.
|
||||||
// annotation, so we should skip it.
|
return nil
|
||||||
continue
|
|
||||||
}
|
|
||||||
statusChecks, err := parseStatusChecks(rawStatusChecks)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
jsonData, err := crdDoc.MarshalJSON()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var crd apiextensions.CustomResourceDefinition
|
|
||||||
err = json.Unmarshal(jsonData, &crd)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
gvrs := getGVRs(crd)
|
|
||||||
for _, gvr := range gvrs {
|
|
||||||
gvk := gvr.GroupVersion().WithKind(crd.Spec.Names.Kind)
|
|
||||||
gvrSingular := gvr.GroupVersion().WithResource(crd.Spec.Names.Singular)
|
|
||||||
sm.mapping[gvr] = statusChecks
|
|
||||||
sm.restMapper.AddSpecific(gvk, gvr, gvrSingular, meta.RESTScopeNamespace)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
statusChecks, err := parseStatusChecks(rawStatusChecks)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
gvrs := getGVRs(crd)
|
||||||
|
for _, gvr := range gvrs {
|
||||||
|
gvk := gvr.GroupVersion().WithKind(crd.Spec.Names.Kind)
|
||||||
|
gvrSingular := gvr.GroupVersion().WithResource(crd.Spec.Names.Singular)
|
||||||
|
sm.mapping[gvr] = statusChecks
|
||||||
|
sm.restMapper.AddSpecific(gvk, gvr, gvrSingular, meta.RESTScopeNamespace)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,12 +15,13 @@
|
|||||||
package cluster_test
|
package cluster_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
|
||||||
"opendev.org/airship/airshipctl/pkg/cluster"
|
"opendev.org/airship/airshipctl/pkg/cluster"
|
||||||
@ -29,65 +30,35 @@ import (
|
|||||||
"opendev.org/airship/airshipctl/testutil"
|
"opendev.org/airship/airshipctl/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type fakeBundle struct {
|
func TestNewStatusMap(t *testing.T) {
|
||||||
document.Bundle
|
|
||||||
|
|
||||||
mockGetByGvk func(string, string, string) ([]document.Document, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fb fakeBundle) GetByGvk(group, version, kind string) ([]document.Document, error) {
|
|
||||||
return fb.mockGetByGvk(group, version, kind)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewStatusMapErrorCases(t *testing.T) {
|
|
||||||
dummyError := errors.New("test error")
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
bundle document.Bundle
|
client *fake.Client
|
||||||
err error
|
err error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "bundle-fails-retrieving-v1-resources",
|
name: "no-failure-on-valid-status-check-annotation",
|
||||||
bundle: fakeBundle{
|
client: fake.NewClient(fake.WithCRDs(makeResourceCRD(annotationValidStatusCheck()))),
|
||||||
mockGetByGvk: func(_, version, _ string) ([]document.Document, error) {
|
err: nil,
|
||||||
if version == "v1" {
|
|
||||||
return nil, dummyError
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
err: dummyError,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "bundle-fails-retrieving-v1beta1-resources",
|
|
||||||
bundle: fakeBundle{
|
|
||||||
mockGetByGvk: func(_, version, _ string) ([]document.Document, error) {
|
|
||||||
if version == "v1beta1" {
|
|
||||||
return nil, dummyError
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
err: dummyError,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "no-failure-when-missing-status-check-annotation",
|
name: "no-failure-when-missing-status-check-annotation",
|
||||||
bundle: testutil.NewTestBundle(t, "testdata/missing-status-check"),
|
client: fake.NewClient(fake.WithCRDs(makeResourceCRD(nil))),
|
||||||
err: nil,
|
err: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing-status",
|
name: "missing-status",
|
||||||
bundle: testutil.NewTestBundle(t, "testdata/missing-status"),
|
client: fake.NewClient(fake.WithCRDs(makeResourceCRD(annotationMissingStatus()))),
|
||||||
err: cluster.ErrInvalidStatusCheck{What: "missing status field"},
|
err: cluster.ErrInvalidStatusCheck{What: "missing status field"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing-condition",
|
name: "missing-condition",
|
||||||
bundle: testutil.NewTestBundle(t, "testdata/missing-condition"),
|
client: fake.NewClient(fake.WithCRDs(makeResourceCRD(annotationMissingCondition()))),
|
||||||
err: cluster.ErrInvalidStatusCheck{What: "missing condition field"},
|
err: cluster.ErrInvalidStatusCheck{What: "missing condition field"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "malformed-status-check",
|
name: "malformed-status-check",
|
||||||
bundle: testutil.NewTestBundle(t, "testdata/malformed-status-check"),
|
client: fake.NewClient(fake.WithCRDs(makeResourceCRD(annotationMalformedStatusCheck()))),
|
||||||
err: cluster.ErrInvalidStatusCheck{What: `unable to parse jsonpath: ` +
|
err: cluster.ErrInvalidStatusCheck{What: `unable to parse jsonpath: ` +
|
||||||
`"{invalid json": invalid character 'i' looking for beginning of object key string`},
|
`"{invalid json": invalid character 'i' looking for beginning of object key string`},
|
||||||
},
|
},
|
||||||
@ -95,7 +66,7 @@ func TestNewStatusMapErrorCases(t *testing.T) {
|
|||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
tt := tt
|
tt := tt
|
||||||
_, err := cluster.NewStatusMap(tt.bundle)
|
_, err := cluster.NewStatusMap(tt.client)
|
||||||
assert.Equal(t, tt.err, err)
|
assert.Equal(t, tt.err, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,7 +75,7 @@ func TestGetStatusForResource(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
selector document.Selector
|
selector document.Selector
|
||||||
testClient *fake.Client
|
client *fake.Client
|
||||||
expectedStatus cluster.Status
|
expectedStatus cluster.Status
|
||||||
err error
|
err error
|
||||||
}{
|
}{
|
||||||
@ -113,7 +84,8 @@ func TestGetStatusForResource(t *testing.T) {
|
|||||||
selector: document.NewSelector().
|
selector: document.NewSelector().
|
||||||
ByGvk("example.com", "v1", "Resource").
|
ByGvk("example.com", "v1", "Resource").
|
||||||
ByName("stable-resource"),
|
ByName("stable-resource"),
|
||||||
testClient: fake.NewClient(
|
client: fake.NewClient(
|
||||||
|
fake.WithCRDs(makeResourceCRD(annotationValidStatusCheck())),
|
||||||
fake.WithDynamicObjects(makeResource("Resource", "stable-resource", "stable")),
|
fake.WithDynamicObjects(makeResource("Resource", "stable-resource", "stable")),
|
||||||
),
|
),
|
||||||
expectedStatus: cluster.Status("Stable"),
|
expectedStatus: cluster.Status("Stable"),
|
||||||
@ -123,7 +95,8 @@ func TestGetStatusForResource(t *testing.T) {
|
|||||||
selector: document.NewSelector().
|
selector: document.NewSelector().
|
||||||
ByGvk("example.com", "v1", "Resource").
|
ByGvk("example.com", "v1", "Resource").
|
||||||
ByName("pending-resource"),
|
ByName("pending-resource"),
|
||||||
testClient: fake.NewClient(
|
client: fake.NewClient(
|
||||||
|
fake.WithCRDs(makeResourceCRD(annotationValidStatusCheck())),
|
||||||
fake.WithDynamicObjects(makeResource("Resource", "pending-resource", "pending")),
|
fake.WithDynamicObjects(makeResource("Resource", "pending-resource", "pending")),
|
||||||
),
|
),
|
||||||
expectedStatus: cluster.Status("Pending"),
|
expectedStatus: cluster.Status("Pending"),
|
||||||
@ -133,28 +106,19 @@ func TestGetStatusForResource(t *testing.T) {
|
|||||||
selector: document.NewSelector().
|
selector: document.NewSelector().
|
||||||
ByGvk("example.com", "v1", "Resource").
|
ByGvk("example.com", "v1", "Resource").
|
||||||
ByName("unknown"),
|
ByName("unknown"),
|
||||||
testClient: fake.NewClient(
|
client: fake.NewClient(
|
||||||
|
fake.WithCRDs(makeResourceCRD(annotationValidStatusCheck())),
|
||||||
fake.WithDynamicObjects(makeResource("Resource", "unknown", "unknown")),
|
fake.WithDynamicObjects(makeResource("Resource", "unknown", "unknown")),
|
||||||
),
|
),
|
||||||
expectedStatus: cluster.UnknownStatus,
|
expectedStatus: cluster.UnknownStatus,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "stable-legacy-is-stable",
|
|
||||||
selector: document.NewSelector().
|
|
||||||
ByGvk("example.com", "v1", "Legacy").
|
|
||||||
ByName("stable-legacy"),
|
|
||||||
testClient: fake.NewClient(
|
|
||||||
fake.WithDynamicObjects(makeResource("Legacy", "stable-legacy", "stable")),
|
|
||||||
),
|
|
||||||
expectedStatus: cluster.Status("Stable"),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "missing-resource-returns-error",
|
name: "missing-resource-returns-error",
|
||||||
selector: document.NewSelector().
|
selector: document.NewSelector().
|
||||||
ByGvk("example.com", "v1", "Missing").
|
ByGvk("example.com", "v1", "Missing").
|
||||||
ByName("missing-resource"),
|
ByName("missing-resource"),
|
||||||
testClient: fake.NewClient(),
|
client: fake.NewClient(),
|
||||||
err: cluster.ErrResourceNotFound{Resource: "missing-resource"},
|
err: cluster.ErrResourceNotFound{Resource: "missing-resource"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,13 +127,13 @@ func TestGetStatusForResource(t *testing.T) {
|
|||||||
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
bundle := testutil.NewTestBundle(t, "testdata/statusmap")
|
bundle := testutil.NewTestBundle(t, "testdata/statusmap")
|
||||||
testStatusMap, err := cluster.NewStatusMap(bundle)
|
testStatusMap, err := cluster.NewStatusMap(tt.client)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
doc, err := bundle.SelectOne(tt.selector)
|
doc, err := bundle.SelectOne(tt.selector)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
actualStatus, err := testStatusMap.GetStatusForResource(tt.testClient, doc)
|
actualStatus, err := testStatusMap.GetStatusForResource(doc)
|
||||||
if tt.err != nil {
|
if tt.err != nil {
|
||||||
assert.EqualError(t, err, tt.err.Error())
|
assert.EqualError(t, err, tt.err.Error())
|
||||||
// We expected an error - no need to check anything else
|
// We expected an error - no need to check anything else
|
||||||
@ -197,3 +161,81 @@ func makeResource(kind, name, state string) *unstructured.Unstructured {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeResourceCRD(annotations map[string]string) *apiextensionsv1.CustomResourceDefinition {
|
||||||
|
return &apiextensionsv1.CustomResourceDefinition{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
Kind: "CustomResourceDefinition",
|
||||||
|
APIVersion: "apiextensions.k8s.io/v1",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "resources.example.com",
|
||||||
|
Annotations: annotations,
|
||||||
|
},
|
||||||
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||||
|
Group: "example.com",
|
||||||
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||||
|
{
|
||||||
|
Name: "v1",
|
||||||
|
Served: true,
|
||||||
|
Storage: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// omitting the openAPIV3Schema for brevity
|
||||||
|
Scope: "Namespaced",
|
||||||
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||||
|
Kind: "Resource",
|
||||||
|
Plural: "resources",
|
||||||
|
Singular: "resource",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func annotationValidStatusCheck() map[string]string {
|
||||||
|
return map[string]string{
|
||||||
|
"airshipit.org/status-check": `
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"status": "Stable",
|
||||||
|
"condition": "@.status.state==\"stable\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"status": "Pending",
|
||||||
|
"condition": "@.status.state==\"pending\""
|
||||||
|
}
|
||||||
|
]`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func annotationMissingStatus() map[string]string {
|
||||||
|
return map[string]string{
|
||||||
|
"airshipit.org/status-check": `
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"condition": "@.status.state==\"stable\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"condition": "@.status.state==\"pending\""
|
||||||
|
}
|
||||||
|
]`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func annotationMissingCondition() map[string]string {
|
||||||
|
return map[string]string{
|
||||||
|
"airshipit.org/status-check": `
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"status": "Stable"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"status": "Pending"
|
||||||
|
}
|
||||||
|
]`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func annotationMalformedStatusCheck() map[string]string {
|
||||||
|
return map[string]string{"airshipit.org/status-check": "{invalid json"}
|
||||||
|
}
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
# this CRD defines a type, but does not have a status-check defined in the
|
|
||||||
# annotations. This is not an error, but a StatusMap won't be able to perform
|
|
||||||
# any validation on resources
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
name: resources.example.com
|
|
||||||
annotations:
|
|
||||||
airshipit.org/status-check: "{invalid json"
|
|
||||||
spec:
|
|
||||||
group: example.com
|
|
||||||
versions:
|
|
||||||
- name: v1
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
status:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
state:
|
|
||||||
type: string
|
|
||||||
scope: Namespaced
|
|
||||||
names:
|
|
||||||
plural: resources
|
|
||||||
singular: resource
|
|
||||||
kind: Resource
|
|
||||||
shortNames:
|
|
||||||
- rsc
|
|
@ -1,2 +0,0 @@
|
|||||||
resources:
|
|
||||||
- crd.yaml
|
|
39
pkg/cluster/testdata/missing-condition/crd.yaml
vendored
39
pkg/cluster/testdata/missing-condition/crd.yaml
vendored
@ -1,39 +0,0 @@
|
|||||||
# this CRD defines a type, but does not have a status-check defined in the
|
|
||||||
# annotations. This is not an error, but a StatusMap won't be able to perform
|
|
||||||
# any validation on resources
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
name: resources.example.com
|
|
||||||
annotations:
|
|
||||||
airshipit.org/status-check: |
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"status": "Stable"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"status": "Pending"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
spec:
|
|
||||||
group: example.com
|
|
||||||
versions:
|
|
||||||
- name: v1
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
status:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
state:
|
|
||||||
type: string
|
|
||||||
scope: Namespaced
|
|
||||||
names:
|
|
||||||
plural: resources
|
|
||||||
singular: resource
|
|
||||||
kind: Resource
|
|
||||||
shortNames:
|
|
||||||
- rsc
|
|
@ -1,2 +0,0 @@
|
|||||||
resources:
|
|
||||||
- crd.yaml
|
|
40
pkg/cluster/testdata/missing-group/crd.yaml
vendored
40
pkg/cluster/testdata/missing-group/crd.yaml
vendored
@ -1,40 +0,0 @@
|
|||||||
# this CRD defines a type, but does not have a status-check defined in the
|
|
||||||
# annotations. This is not an error, but a StatusMap won't be able to perform
|
|
||||||
# any validation on resources
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
name: resources.example.com
|
|
||||||
annotations:
|
|
||||||
airshipit.org/status-check: |
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"status": "Stable",
|
|
||||||
"condition": "@.status.state==\"stable\""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"status": "Pending",
|
|
||||||
"condition": "@.status.state==\"pending\""
|
|
||||||
}
|
|
||||||
]
|
|
||||||
spec:
|
|
||||||
versions:
|
|
||||||
- name: v1
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
status:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
state:
|
|
||||||
type: string
|
|
||||||
scope: Namespaced
|
|
||||||
names:
|
|
||||||
plural: resources
|
|
||||||
singular: resource
|
|
||||||
kind: Resource
|
|
||||||
shortNames:
|
|
||||||
- rsc
|
|
@ -1,2 +0,0 @@
|
|||||||
resources:
|
|
||||||
- crd.yaml
|
|
40
pkg/cluster/testdata/missing-kind/crd.yaml
vendored
40
pkg/cluster/testdata/missing-kind/crd.yaml
vendored
@ -1,40 +0,0 @@
|
|||||||
# this CRD defines a type, but does not have a status-check defined in the
|
|
||||||
# annotations. This is not an error, but a StatusMap won't be able to perform
|
|
||||||
# any validation on resources
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
name: resources.example.com
|
|
||||||
annotations:
|
|
||||||
airshipit.org/status-check: |
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"status": "Stable",
|
|
||||||
"condition": "@.status.state==\"stable\""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"status": "Pending",
|
|
||||||
"condition": "@.status.state==\"pending\""
|
|
||||||
}
|
|
||||||
]
|
|
||||||
spec:
|
|
||||||
group: example.com
|
|
||||||
versions:
|
|
||||||
- name: v1
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
status:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
state:
|
|
||||||
type: string
|
|
||||||
scope: Namespaced
|
|
||||||
names:
|
|
||||||
plural: resources
|
|
||||||
singular: resource
|
|
||||||
shortNames:
|
|
||||||
- rsc
|
|
@ -1,2 +0,0 @@
|
|||||||
resources:
|
|
||||||
- crd.yaml
|
|
40
pkg/cluster/testdata/missing-plural/crd.yaml
vendored
40
pkg/cluster/testdata/missing-plural/crd.yaml
vendored
@ -1,40 +0,0 @@
|
|||||||
# this CRD defines a type, but does not have a status-check defined in the
|
|
||||||
# annotations. This is not an error, but a StatusMap won't be able to perform
|
|
||||||
# any validation on resources
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
name: resources.example.com
|
|
||||||
annotations:
|
|
||||||
airshipit.org/status-check: |
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"status": "Stable",
|
|
||||||
"condition": "@.status.state==\"stable\""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"status": "Pending",
|
|
||||||
"condition": "@.status.state==\"pending\""
|
|
||||||
}
|
|
||||||
]
|
|
||||||
spec:
|
|
||||||
group: example.com
|
|
||||||
versions:
|
|
||||||
- name: v1
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
status:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
state:
|
|
||||||
type: string
|
|
||||||
scope: Namespaced
|
|
||||||
names:
|
|
||||||
singular: resource
|
|
||||||
kind: Resource
|
|
||||||
shortNames:
|
|
||||||
- rsc
|
|
@ -1,2 +0,0 @@
|
|||||||
resources:
|
|
||||||
- crd.yaml
|
|
40
pkg/cluster/testdata/missing-singular/crd.yaml
vendored
40
pkg/cluster/testdata/missing-singular/crd.yaml
vendored
@ -1,40 +0,0 @@
|
|||||||
# this CRD defines a type, but does not have a status-check defined in the
|
|
||||||
# annotations. This is not an error, but a StatusMap won't be able to perform
|
|
||||||
# any validation on resources
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
name: resources.example.com
|
|
||||||
annotations:
|
|
||||||
airshipit.org/status-check: |
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"status": "Stable",
|
|
||||||
"condition": "@.status.state==\"stable\""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"status": "Pending",
|
|
||||||
"condition": "@.status.state==\"pending\""
|
|
||||||
}
|
|
||||||
]
|
|
||||||
spec:
|
|
||||||
group: example.com
|
|
||||||
versions:
|
|
||||||
- name: v1
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
status:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
state:
|
|
||||||
type: string
|
|
||||||
scope: Namespaced
|
|
||||||
names:
|
|
||||||
plural: resources
|
|
||||||
kind: Resource
|
|
||||||
shortNames:
|
|
||||||
- rsc
|
|
@ -1,2 +0,0 @@
|
|||||||
resources:
|
|
||||||
- crd.yaml
|
|
@ -1,29 +0,0 @@
|
|||||||
# this CRD defines a type, but does not have a status-check defined in the
|
|
||||||
# annotations. This is not an error, but a StatusMap won't be able to perform
|
|
||||||
# any validation on resources
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
name: resources.example.com
|
|
||||||
spec:
|
|
||||||
group: example.com
|
|
||||||
versions:
|
|
||||||
- name: v1
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
status:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
state:
|
|
||||||
type: string
|
|
||||||
scope: Namespaced
|
|
||||||
names:
|
|
||||||
plural: resources
|
|
||||||
singular: resource
|
|
||||||
kind: Resource
|
|
||||||
shortNames:
|
|
||||||
- rsc
|
|
@ -1,2 +0,0 @@
|
|||||||
resources:
|
|
||||||
- crd.yaml
|
|
39
pkg/cluster/testdata/missing-status/crd.yaml
vendored
39
pkg/cluster/testdata/missing-status/crd.yaml
vendored
@ -1,39 +0,0 @@
|
|||||||
# this CRD defines a type, but does not have a status-check defined in the
|
|
||||||
# annotations. This is not an error, but a StatusMap won't be able to perform
|
|
||||||
# any validation on resources
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
name: resources.example.com
|
|
||||||
annotations:
|
|
||||||
airshipit.org/status-check: |
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"condition": "@.status.state==\"stable\""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"condition": "@.status.state==\"pending\""
|
|
||||||
}
|
|
||||||
]
|
|
||||||
spec:
|
|
||||||
group: example.com
|
|
||||||
versions:
|
|
||||||
- name: v1
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
status:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
state:
|
|
||||||
type: string
|
|
||||||
scope: Namespaced
|
|
||||||
names:
|
|
||||||
plural: resources
|
|
||||||
singular: resource
|
|
||||||
kind: Resource
|
|
||||||
shortNames:
|
|
||||||
- rsc
|
|
@ -1,2 +0,0 @@
|
|||||||
resources:
|
|
||||||
- crd.yaml
|
|
28
pkg/cluster/testdata/missing-version/crd.yaml
vendored
28
pkg/cluster/testdata/missing-version/crd.yaml
vendored
@ -1,28 +0,0 @@
|
|||||||
# this CRD defines a type, but does not have a status-check defined in the
|
|
||||||
# annotations. This is not an error, but a StatusMap won't be able to perform
|
|
||||||
# any validation on resources
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
name: resources.example.com
|
|
||||||
annotations:
|
|
||||||
airshipit.org/status-check: |
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"status": "Stable",
|
|
||||||
"condition": "@.status.state==\"stable\""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"status": "Pending",
|
|
||||||
"condition": "@.status.state==\"pending\""
|
|
||||||
}
|
|
||||||
]
|
|
||||||
spec:
|
|
||||||
group: example.com
|
|
||||||
scope: Namespaced
|
|
||||||
names:
|
|
||||||
plural: resources
|
|
||||||
singular: resource
|
|
||||||
kind: Resource
|
|
||||||
shortNames:
|
|
||||||
- rsc
|
|
@ -1,2 +0,0 @@
|
|||||||
resources:
|
|
||||||
- crd.yaml
|
|
Loading…
x
Reference in New Issue
Block a user