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:
Jared Watts 2019-05-07 15:22:10 -07:00 committed by GitHub
commit 83cf0f56c0
11 changed files with 896 additions and 5 deletions

1
Gopkg.lock generated
View File

@ -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",

View File

@ -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,

View File

@ -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 (

View File

@ -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 (

View File

@ -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)
}

View File

@ -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)
}
}
}

View File

@ -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

View File

@ -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{})
}

View File

@ -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"`
}

View File

@ -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())
}

View File

@ -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
}