Merge pull request #397 from jbw976/installer-design
design proposal and API for mechanism to extend Crossplane with new out-of-tree functionality
This commit is contained in:
commit
83cf0f56c0
|
|
@ -1356,6 +1356,7 @@
|
|||
"gopkg.in/alecthomas/kingpin.v2",
|
||||
"k8s.io/api/apps/v1",
|
||||
"k8s.io/api/core/v1",
|
||||
"k8s.io/api/rbac/v1",
|
||||
"k8s.io/apimachinery/pkg/api/errors",
|
||||
"k8s.io/apimachinery/pkg/api/meta",
|
||||
"k8s.io/apimachinery/pkg/api/resource",
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import (
|
|||
"github.com/crossplaneio/crossplane/pkg/apis/cache"
|
||||
"github.com/crossplaneio/crossplane/pkg/apis/compute"
|
||||
"github.com/crossplaneio/crossplane/pkg/apis/core"
|
||||
"github.com/crossplaneio/crossplane/pkg/apis/extensions"
|
||||
"github.com/crossplaneio/crossplane/pkg/apis/gcp"
|
||||
"github.com/crossplaneio/crossplane/pkg/apis/storage"
|
||||
"github.com/crossplaneio/crossplane/pkg/apis/workload"
|
||||
|
|
@ -41,6 +42,7 @@ func init() {
|
|||
cache.AddToScheme,
|
||||
compute.AddToScheme,
|
||||
core.AddToScheme,
|
||||
extensions.AddToScheme,
|
||||
gcp.AddToScheme,
|
||||
storage.AddToScheme,
|
||||
workload.AddToScheme,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package core contains Kubernetes API groups for AWS cloud provider.
|
||||
// Package core contains Kubernetes API groups for the Crossplane core API.
|
||||
package core
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -31,10 +31,11 @@ import (
|
|||
|
||||
// Kubernetes Group, Version, and Kind metadata.
|
||||
const (
|
||||
Group = "core.crossplane.io"
|
||||
Version = "v1alpha1"
|
||||
ResourceClassKind = "resourceclass"
|
||||
APIVersion = Group + "/" + Version
|
||||
Group = "core.crossplane.io"
|
||||
Version = "v1alpha1"
|
||||
APIVersion = Group + "/" + Version
|
||||
ResourceClassKind = "resourceclass"
|
||||
ResourceClassKindAPIVersion = ResourceClassKind + "." + APIVersion
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
Copyright 2019 The Crossplane Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package extensions contains Kubernetes API groups for Crossplane extensions.
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"github.com/crossplaneio/crossplane/pkg/apis/extensions/v1alpha1"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Register the types with the Scheme so the components can map objects to GroupVersionKinds and back
|
||||
AddToSchemes = append(AddToSchemes, v1alpha1.SchemeBuilder.AddToScheme)
|
||||
}
|
||||
|
||||
// AddToSchemes may be used to add all resources defined in the project to a Scheme
|
||||
var AddToSchemes runtime.SchemeBuilder
|
||||
|
||||
// AddToScheme adds all Resources to the Scheme
|
||||
func AddToScheme(s *runtime.Scheme) error {
|
||||
return AddToSchemes.AddToScheme(s)
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
Copyright 2018 The Crossplane Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package extensions contains Kubernetes API groups for Crossplane extensions.
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/crossplaneio/crossplane/pkg/apis/extensions/v1alpha1"
|
||||
)
|
||||
|
||||
func TestAddToScheme(t *testing.T) {
|
||||
s := runtime.NewScheme()
|
||||
if err := AddToScheme(s); err != nil {
|
||||
t.Errorf("AddToScheme() error = %v", err)
|
||||
}
|
||||
gvs := []schema.GroupVersion{
|
||||
v1alpha1.SchemeGroupVersion,
|
||||
}
|
||||
for _, gv := range gvs {
|
||||
if !s.IsVersionRegistered(gv) {
|
||||
t.Errorf("AddToScheme() %v should be registered", gv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
Copyright 2019 The Crossplane Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package v1alpha1 contains API Schema definitions for the crossplane extensions v1alpha1 API group
|
||||
// +k8s:openapi-gen=true
|
||||
// +k8s:deepcopy-gen=package,register
|
||||
// +k8s:conversion-gen=github.com/crossplaneio/crossplane/pkg/apis/extensions
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +groupName=extensions.crossplane.io
|
||||
package v1alpha1
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
Copyright 2019 The Crossplane Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// NOTE: Boilerplate only. Ignore this file.
|
||||
|
||||
// Package v1alpha1 contains API Schema definitions for the crossplane extensions v1alpha1 API group
|
||||
// +k8s:openapi-gen=true
|
||||
// +k8s:deepcopy-gen=package,register
|
||||
// +k8s:conversion-gen=github.com/crossplaneio/crossplane/pkg/apis/extensions
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +groupName=extensions.crossplane.io
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/runtime/scheme"
|
||||
)
|
||||
|
||||
// Kubernetes Group, Version, and Kind metadata.
|
||||
const (
|
||||
Group = "extensions.crossplane.io"
|
||||
Version = "v1alpha1"
|
||||
APIVersion = Group + "/" + Version
|
||||
ExtensionRequestKind = "extensionrequest"
|
||||
ExtensionRequestKindAPIVersion = ExtensionRequestKind + "." + APIVersion
|
||||
ExtensionKind = "extension"
|
||||
ExtensionKindAPIVersion = ExtensionKind + "." + APIVersion
|
||||
)
|
||||
|
||||
var (
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
SchemeGroupVersion = schema.GroupVersion{Group: Group, Version: Version}
|
||||
|
||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
|
||||
SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}
|
||||
)
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&ExtensionRequest{}, &ExtensionRequestList{})
|
||||
SchemeBuilder.Register(&Extension{}, &ExtensionList{})
|
||||
}
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
Copyright 2019 The Crossplane Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
apps "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
rbac "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
corev1alpha1 "github.com/crossplaneio/crossplane/pkg/apis/core/v1alpha1"
|
||||
)
|
||||
|
||||
// TODO: how do we pretty print conditioned status items? There may be multiple of them, and they
|
||||
// can have varying status (e.g., True, False, Unknown)
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ExtensionRequest is the CRD type for a request to add an extension to Crossplane.
|
||||
// +k8s:openapi-gen=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="STATUS",type="string",JSONPath=".status.conditions[0].type"
|
||||
// +kubebuilder:printcolumn:name="SOURCE",type="string",JSONPath=".spec.source"
|
||||
// +kubebuilder:printcolumn:name="PACKAGE",type="string",JSONPath=".spec.package"
|
||||
// +kubebuilder:printcolumn:name="CRD",type="string",JSONPath=".spec.crd"
|
||||
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
|
||||
type ExtensionRequest struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ExtensionRequestSpec `json:"spec,omitempty"`
|
||||
Status ExtensionRequestStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ExtensionRequestList contains a list of ExtensionRequest
|
||||
type ExtensionRequestList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []ExtensionRequest `json:"items"`
|
||||
}
|
||||
|
||||
// ExtensionRequestSpec specifies details about a request to add an extension to Crossplane.
|
||||
type ExtensionRequestSpec struct {
|
||||
// Source is the domain name for the extension registry hosting the extension being requested,
|
||||
// e.g., registry.crossplane.io
|
||||
Source string `json:"source,omitempty"`
|
||||
|
||||
// Package is the name of the extension package that is being requested, e.g., myapp.
|
||||
// Either Package or CustomResourceDefinition can be specified.
|
||||
Package string `json:"package,omitempty"`
|
||||
|
||||
// CustomResourceDefinition is the full name of a CRD that is owned by the extension being
|
||||
// requested. This can be a convenient way of installing an extension when the desired
|
||||
// CRD is known, but the package name that contains it is not known.
|
||||
// Either Package or CustomResourceDefinition can be specified.
|
||||
CustomResourceDefinition string `json:"crd,omitempty"`
|
||||
}
|
||||
|
||||
// ExtensionRequestStatus defines the observed state of ExtensionRequest
|
||||
type ExtensionRequestStatus struct {
|
||||
corev1alpha1.ConditionedStatus
|
||||
InstallJob *corev1.ObjectReference `json:"installJob,omitempty"`
|
||||
ExtensionRecord *corev1.ObjectReference `json:"extensionRecord,omitempty"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// Extension is the CRD type for a request to add an extension to Crossplane.
|
||||
// +k8s:openapi-gen=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="STATUS",type="string",JSONPath=".status.conditions[0].type"
|
||||
// +kubebuilder:printcolumn:name="DESCRIPTION",type="string",JSONPath=".spec.description"
|
||||
// +kubebuilder:printcolumn:name="VERSION",type="string",JSONPath=".spec.version"
|
||||
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
|
||||
type Extension struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ExtensionSpec `json:"spec,omitempty"`
|
||||
Status ExtensionStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ExtensionList contains a list of Extension
|
||||
type ExtensionList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Extension `json:"items"`
|
||||
}
|
||||
|
||||
// ExtensionSpec specifies details about an extension that has been added to Crossplane
|
||||
type ExtensionSpec struct {
|
||||
AppMetadataSpec `json:",inline"`
|
||||
CRDs CRDList `json:"customresourcedefinitions,omitempty"`
|
||||
Controller ControllerSpec `json:"controller,omitempty"`
|
||||
Permissions PermissionsSpec `json:"permissions,omitempty"`
|
||||
}
|
||||
|
||||
// ExtensionStatus defines the observed state of Extension
|
||||
type ExtensionStatus struct {
|
||||
corev1alpha1.ConditionedStatus
|
||||
}
|
||||
|
||||
// AppMetadataSpec defines metadata about the extension application
|
||||
type AppMetadataSpec struct {
|
||||
Title string `json:"title,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
Icons []IconSpec `json:"icons,omitempty"`
|
||||
Maintainers []ContributorSpec `json:"maintainers,omitempty"`
|
||||
Owners []ContributorSpec `json:"owners,omitempty"`
|
||||
Company string `json:"company,omitempty"`
|
||||
Keywords []string `json:"keywords,omitempty"`
|
||||
Links []LinkSpec `json:"links,omitempty"`
|
||||
License string `json:"license,omitempty"`
|
||||
}
|
||||
|
||||
// CRDList is the full list of CRDs that this extension owns and depends on
|
||||
type CRDList struct {
|
||||
// Owned is the list of CRDs that this extension defines and owns
|
||||
Owned []metav1.TypeMeta `json:"owns,omitempty"`
|
||||
|
||||
// DependsOn is the list of CRDs that this extension depends on. This data drives the
|
||||
// dependency resolution process.
|
||||
DependsOn []metav1.TypeMeta `json:"dependsOn,omitempty"`
|
||||
}
|
||||
|
||||
// NewCRDList creates a new CRDList with its members initialized.
|
||||
func NewCRDList() *CRDList {
|
||||
return &CRDList{
|
||||
Owned: []metav1.TypeMeta{},
|
||||
DependsOn: []metav1.TypeMeta{},
|
||||
}
|
||||
}
|
||||
|
||||
// IconSpec defines the icon for an extension
|
||||
type IconSpec struct {
|
||||
Base64IconData string `json:"base64Data"`
|
||||
MediaType string `json:"mediatype"`
|
||||
}
|
||||
|
||||
// ContributorSpec defines a contributor for an extension (e.g., maintainer, owner, etc.)
|
||||
type ContributorSpec struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
}
|
||||
|
||||
// LinkSpec defines a useful link about an extension (e.g., homepage, about page, etc.)
|
||||
type LinkSpec struct {
|
||||
Description string `json:"description,omitempty"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
// ControllerSpec defines the controller that implements the logic for an extension, which can come
|
||||
// in different flavors. A golang code (controller-runtime) controller with a managing Deployment
|
||||
// is all that is supported currently, but more types will come in the future (e.g., templates,
|
||||
// functions/hooks, templates, a new DSL, etc.
|
||||
type ControllerSpec struct {
|
||||
Deployment *ControllerDeployment `json:"deployment,omitempty"`
|
||||
}
|
||||
|
||||
// ControllerDeployment defines a controller for an extension that is managed by a Deployment.
|
||||
type ControllerDeployment struct {
|
||||
Name string `json:"name"`
|
||||
Spec apps.DeploymentSpec `json:"spec"`
|
||||
}
|
||||
|
||||
// PermissionsSpec defines the permissions that an extension will require to operate.
|
||||
type PermissionsSpec struct {
|
||||
Rules []rbac.PolicyRule `json:"rules,omitempty"`
|
||||
}
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
Copyright 2018 The Crossplane Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
"golang.org/x/net/context"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/crossplaneio/crossplane/pkg/test"
|
||||
)
|
||||
|
||||
const (
|
||||
namespace = "default"
|
||||
name = "test-instance"
|
||||
)
|
||||
|
||||
var (
|
||||
ctx = context.TODO()
|
||||
c client.Client
|
||||
|
||||
key = types.NamespacedName{Name: name, Namespace: namespace}
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
t := test.NewEnv(namespace, SchemeBuilder.SchemeBuilder, test.CRDs())
|
||||
c = t.StartClient()
|
||||
t.StopAndExit(m.Run())
|
||||
}
|
||||
|
||||
func TestExtensionRequest(t *testing.T) {
|
||||
g := NewGomegaWithT(t)
|
||||
|
||||
created := &ExtensionRequest{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
},
|
||||
Spec: ExtensionRequestSpec{
|
||||
Source: "registry.crossplane.io",
|
||||
Package: "testpackage:v0.1",
|
||||
},
|
||||
}
|
||||
|
||||
// Test Create
|
||||
fetched := &ExtensionRequest{}
|
||||
g.Expect(c.Create(ctx, created)).NotTo(HaveOccurred())
|
||||
|
||||
g.Expect(c.Get(ctx, key, fetched)).NotTo(HaveOccurred())
|
||||
g.Expect(fetched).To(Equal(created))
|
||||
|
||||
// Test Updating the annotations
|
||||
updated := fetched.DeepCopy()
|
||||
updated.Annotations = map[string]string{"hello": "world"}
|
||||
g.Expect(c.Update(ctx, updated)).NotTo(HaveOccurred())
|
||||
|
||||
g.Expect(c.Get(ctx, key, fetched)).NotTo(HaveOccurred())
|
||||
g.Expect(fetched).To(Equal(updated))
|
||||
|
||||
// Test Delete
|
||||
g.Expect(c.Delete(ctx, fetched)).NotTo(HaveOccurred())
|
||||
g.Expect(c.Get(ctx, key, fetched)).To(HaveOccurred())
|
||||
}
|
||||
|
||||
func TestExtension(t *testing.T) {
|
||||
g := NewGomegaWithT(t)
|
||||
|
||||
created := &Extension{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
},
|
||||
Spec: ExtensionSpec{
|
||||
AppMetadataSpec: AppMetadataSpec{
|
||||
Title: "myapp",
|
||||
Version: "v0.1.0",
|
||||
Owners: []ContributorSpec{
|
||||
{Name: "dev1", Email: "dev1@foo.com"},
|
||||
},
|
||||
Company: "foo-inc.",
|
||||
Keywords: []string{"app", "useless", "example"},
|
||||
Links: []LinkSpec{
|
||||
{
|
||||
Description: "about page",
|
||||
URL: "https://app.foo.io",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Test Create
|
||||
fetched := &Extension{}
|
||||
g.Expect(c.Create(ctx, created)).NotTo(HaveOccurred())
|
||||
|
||||
g.Expect(c.Get(ctx, key, fetched)).NotTo(HaveOccurred())
|
||||
g.Expect(fetched).To(Equal(created))
|
||||
|
||||
// Test Updating the annotations
|
||||
updated := fetched.DeepCopy()
|
||||
updated.Annotations = map[string]string{"hello": "world"}
|
||||
g.Expect(c.Update(ctx, updated)).NotTo(HaveOccurred())
|
||||
|
||||
g.Expect(c.Get(ctx, key, fetched)).NotTo(HaveOccurred())
|
||||
g.Expect(fetched).To(Equal(updated))
|
||||
|
||||
// Test Delete
|
||||
g.Expect(c.Delete(ctx, fetched)).NotTo(HaveOccurred())
|
||||
g.Expect(c.Get(ctx, key, fetched)).To(HaveOccurred())
|
||||
}
|
||||
|
||||
func TestNewCRDList(t *testing.T) {
|
||||
g := NewGomegaWithT(t)
|
||||
crdList := NewCRDList()
|
||||
g.Expect(crdList).NotTo(BeNil())
|
||||
g.Expect(crdList.Owned).NotTo(BeNil())
|
||||
g.Expect(crdList.DependsOn).NotTo(BeNil())
|
||||
}
|
||||
|
|
@ -0,0 +1,405 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2018 The Crossplane Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Code generated by main. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AppMetadataSpec) DeepCopyInto(out *AppMetadataSpec) {
|
||||
*out = *in
|
||||
if in.Icons != nil {
|
||||
in, out := &in.Icons, &out.Icons
|
||||
*out = make([]IconSpec, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Maintainers != nil {
|
||||
in, out := &in.Maintainers, &out.Maintainers
|
||||
*out = make([]ContributorSpec, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Owners != nil {
|
||||
in, out := &in.Owners, &out.Owners
|
||||
*out = make([]ContributorSpec, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Keywords != nil {
|
||||
in, out := &in.Keywords, &out.Keywords
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Links != nil {
|
||||
in, out := &in.Links, &out.Links
|
||||
*out = make([]LinkSpec, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppMetadataSpec.
|
||||
func (in *AppMetadataSpec) DeepCopy() *AppMetadataSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AppMetadataSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CRDList) DeepCopyInto(out *CRDList) {
|
||||
*out = *in
|
||||
if in.Owned != nil {
|
||||
in, out := &in.Owned, &out.Owned
|
||||
*out = make([]v1.TypeMeta, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.DependsOn != nil {
|
||||
in, out := &in.DependsOn, &out.DependsOn
|
||||
*out = make([]v1.TypeMeta, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CRDList.
|
||||
func (in *CRDList) DeepCopy() *CRDList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CRDList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ContributorSpec) DeepCopyInto(out *ContributorSpec) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContributorSpec.
|
||||
func (in *ContributorSpec) DeepCopy() *ContributorSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ContributorSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ControllerDeployment) DeepCopyInto(out *ControllerDeployment) {
|
||||
*out = *in
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerDeployment.
|
||||
func (in *ControllerDeployment) DeepCopy() *ControllerDeployment {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ControllerDeployment)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ControllerSpec) DeepCopyInto(out *ControllerSpec) {
|
||||
*out = *in
|
||||
if in.Deployment != nil {
|
||||
in, out := &in.Deployment, &out.Deployment
|
||||
*out = new(ControllerDeployment)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerSpec.
|
||||
func (in *ControllerSpec) DeepCopy() *ControllerSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ControllerSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Extension) DeepCopyInto(out *Extension) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Extension.
|
||||
func (in *Extension) DeepCopy() *Extension {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Extension)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Extension) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtensionList) DeepCopyInto(out *ExtensionList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.ListMeta = in.ListMeta
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Extension, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionList.
|
||||
func (in *ExtensionList) DeepCopy() *ExtensionList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtensionList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ExtensionList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtensionRequest) DeepCopyInto(out *ExtensionRequest) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Spec = in.Spec
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionRequest.
|
||||
func (in *ExtensionRequest) DeepCopy() *ExtensionRequest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtensionRequest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ExtensionRequest) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtensionRequestList) DeepCopyInto(out *ExtensionRequestList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.ListMeta = in.ListMeta
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]ExtensionRequest, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionRequestList.
|
||||
func (in *ExtensionRequestList) DeepCopy() *ExtensionRequestList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtensionRequestList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ExtensionRequestList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtensionRequestSpec) DeepCopyInto(out *ExtensionRequestSpec) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionRequestSpec.
|
||||
func (in *ExtensionRequestSpec) DeepCopy() *ExtensionRequestSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtensionRequestSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtensionRequestStatus) DeepCopyInto(out *ExtensionRequestStatus) {
|
||||
*out = *in
|
||||
in.ConditionedStatus.DeepCopyInto(&out.ConditionedStatus)
|
||||
if in.InstallJob != nil {
|
||||
in, out := &in.InstallJob, &out.InstallJob
|
||||
*out = new(corev1.ObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
if in.ExtensionRecord != nil {
|
||||
in, out := &in.ExtensionRecord, &out.ExtensionRecord
|
||||
*out = new(corev1.ObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionRequestStatus.
|
||||
func (in *ExtensionRequestStatus) DeepCopy() *ExtensionRequestStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtensionRequestStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtensionSpec) DeepCopyInto(out *ExtensionSpec) {
|
||||
*out = *in
|
||||
in.AppMetadataSpec.DeepCopyInto(&out.AppMetadataSpec)
|
||||
in.CRDs.DeepCopyInto(&out.CRDs)
|
||||
in.Controller.DeepCopyInto(&out.Controller)
|
||||
in.Permissions.DeepCopyInto(&out.Permissions)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionSpec.
|
||||
func (in *ExtensionSpec) DeepCopy() *ExtensionSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtensionSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtensionStatus) DeepCopyInto(out *ExtensionStatus) {
|
||||
*out = *in
|
||||
in.ConditionedStatus.DeepCopyInto(&out.ConditionedStatus)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionStatus.
|
||||
func (in *ExtensionStatus) DeepCopy() *ExtensionStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtensionStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *IconSpec) DeepCopyInto(out *IconSpec) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IconSpec.
|
||||
func (in *IconSpec) DeepCopy() *IconSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(IconSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LinkSpec) DeepCopyInto(out *LinkSpec) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LinkSpec.
|
||||
func (in *LinkSpec) DeepCopy() *LinkSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LinkSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PermissionsSpec) DeepCopyInto(out *PermissionsSpec) {
|
||||
*out = *in
|
||||
if in.Rules != nil {
|
||||
in, out := &in.Rules, &out.Rules
|
||||
*out = make([]rbacv1.PolicyRule, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PermissionsSpec.
|
||||
func (in *PermissionsSpec) DeepCopy() *PermissionsSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PermissionsSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
Loading…
Reference in New Issue