diff --git a/examples/common/00-prereqs.yaml b/examples/common/00-prereqs.yaml index 53660427e..c9c096415 100644 --- a/examples/common/00-prereqs.yaml +++ b/examples/common/00-prereqs.yaml @@ -147,6 +147,21 @@ spec: plural: resticrepositories kind: ResticRepository +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: backupstoragelocations.ark.heptio.com + labels: + component: ark +spec: + group: ark.heptio.com + version: v1 + scope: Namespaced + names: + plural: backupstoragelocations + kind: BackupStorageLocation + --- apiVersion: v1 kind: Namespace diff --git a/pkg/apis/ark/v1/backup.go b/pkg/apis/ark/v1/backup.go index 041d3b5b1..8aef922ca 100644 --- a/pkg/apis/ark/v1/backup.go +++ b/pkg/apis/ark/v1/backup.go @@ -16,7 +16,9 @@ limitations under the License. package v1 -import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) // BackupSpec defines the specification for an Ark backup. type BackupSpec struct { @@ -56,6 +58,9 @@ type BackupSpec struct { // Hooks represent custom behaviors that should be executed at different phases of the backup. Hooks BackupHooks `json:"hooks"` + + // StorageLocation is a string containing the name of a BackupStorageLocation where the backup should be stored. + StorageLocation string `json:"storageLocation"` } // BackupHooks contains custom behaviors that should be executed at different phases of the backup. diff --git a/pkg/apis/ark/v1/backup_storage_location.go b/pkg/apis/ark/v1/backup_storage_location.go new file mode 100644 index 000000000..adafec1b7 --- /dev/null +++ b/pkg/apis/ark/v1/backup_storage_location.go @@ -0,0 +1,93 @@ +/* +Copyright 2018 the Heptio Ark contributors. + +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 v1 + +import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// BackupStorageLocation is a location where Ark stores backup objects. +type BackupStorageLocation struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + + Spec BackupStorageLocationSpec `json:"spec"` + Status BackupStorageLocationStatus `json:"status"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// BackupStorageLocationList is a list of BackupStorageLocations. +type BackupStorageLocationList struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + Items []BackupStorageLocation `json:"items"` +} + +// StorageType represents the type of storage that a backup location uses. +// ObjectStorage must be non-nil, since it is currently the only supported StorageType. +type StorageType struct { + ObjectStorage *ObjectStorageLocation `json:"objectStorage,omitempty"` +} + +// ObjectStorageLocation specifies the settings necessary to connect to a provider's object storage. +type ObjectStorageLocation struct { + // Bucket is the bucket to use for object storage. + Bucket string `json:"bucket"` + + // Prefix is the path inside a bucket to use for Ark storage. Optional. + Prefix string `json:"prefix"` +} + +// BackupStorageLocationSpec defines the specification for an Ark BackupStorageLocation. +type BackupStorageLocationSpec struct { + // Provider is the provider of the backup storage. + Provider string `json:"provider"` + + // Config is for provider-specific configuration fields. + Config map[string]string `json:"config"` + + StorageType `json:",inline"` +} + +// BackupStorageLocationPhase is the lifecyle phase of an Ark BackupStorageLocation. +type BackupStorageLocationPhase string + +const ( + // BackupStorageLocationPhaseAvailable means the location is available to read and write from. + BackupStorageLocationPhaseAvailable BackupStorageLocationPhase = "Available" + + // BackupStorageLocationPhaseUnavailable means the location is unavailable to read and write from. + BackupStorageLocationPhaseUnavailable BackupStorageLocationPhase = "Unavailable" +) + +// BackupStorageLocationAccessMode represents the permissions for a BackupStorageLocation. +type BackupStorageLocationAccessMode string + +const ( + // BackupStorageLocationAccessModeReadOnly represents read-only access to a BackupStorageLocation. + BackupStorageLocationAccessModeReadOnly BackupStorageLocationAccessMode = "ReadOnly" + + // BackupStorageLocationAccessModeReadWrite represents read and write access to a BackupStorageLocation. + BackupStorageLocationAccessModeReadWrite BackupStorageLocationAccessMode = "ReadWrite" +) + +// BackupStorageLocationStatus describes the current status of an Ark BackupStorageLocation. +type BackupStorageLocationStatus struct { + Phase BackupStorageLocationPhase `json:"phase,omitempty"` + AccessMode BackupStorageLocationAccessMode `json:"accessMode,omitempty"` +} diff --git a/pkg/apis/ark/v1/register.go b/pkg/apis/ark/v1/register.go index 1e9913c9e..5d70dcc76 100644 --- a/pkg/apis/ark/v1/register.go +++ b/pkg/apis/ark/v1/register.go @@ -59,15 +59,16 @@ func newTypeInfo(pluralName string, itemType, itemListType runtime.Object) typeI // API group, keyed on Kind. func CustomResources() map[string]typeInfo { return map[string]typeInfo{ - "Backup": newTypeInfo("backups", &Backup{}, &BackupList{}), - "Restore": newTypeInfo("restores", &Restore{}, &RestoreList{}), - "Schedule": newTypeInfo("schedules", &Schedule{}, &ScheduleList{}), - "Config": newTypeInfo("configs", &Config{}, &ConfigList{}), - "DownloadRequest": newTypeInfo("downloadrequests", &DownloadRequest{}, &DownloadRequestList{}), - "DeleteBackupRequest": newTypeInfo("deletebackuprequests", &DeleteBackupRequest{}, &DeleteBackupRequestList{}), - "PodVolumeBackup": newTypeInfo("podvolumebackups", &PodVolumeBackup{}, &PodVolumeBackupList{}), - "PodVolumeRestore": newTypeInfo("podvolumerestores", &PodVolumeRestore{}, &PodVolumeRestoreList{}), - "ResticRepository": newTypeInfo("resticrepositories", &ResticRepository{}, &ResticRepositoryList{}), + "Backup": newTypeInfo("backups", &Backup{}, &BackupList{}), + "Restore": newTypeInfo("restores", &Restore{}, &RestoreList{}), + "Schedule": newTypeInfo("schedules", &Schedule{}, &ScheduleList{}), + "Config": newTypeInfo("configs", &Config{}, &ConfigList{}), + "DownloadRequest": newTypeInfo("downloadrequests", &DownloadRequest{}, &DownloadRequestList{}), + "DeleteBackupRequest": newTypeInfo("deletebackuprequests", &DeleteBackupRequest{}, &DeleteBackupRequestList{}), + "PodVolumeBackup": newTypeInfo("podvolumebackups", &PodVolumeBackup{}, &PodVolumeBackupList{}), + "PodVolumeRestore": newTypeInfo("podvolumerestores", &PodVolumeRestore{}, &PodVolumeRestoreList{}), + "ResticRepository": newTypeInfo("resticrepositories", &ResticRepository{}, &ResticRepositoryList{}), + "BackupStorageLocation": newTypeInfo("backupstoragelocations", &BackupStorageLocation{}, &BackupStorageLocationList{}), } } diff --git a/pkg/apis/ark/v1/zz_generated.deepcopy.go b/pkg/apis/ark/v1/zz_generated.deepcopy.go index 7915be376..0d55e70b6 100644 --- a/pkg/apis/ark/v1/zz_generated.deepcopy.go +++ b/pkg/apis/ark/v1/zz_generated.deepcopy.go @@ -301,6 +301,107 @@ func (in *BackupStatus) DeepCopy() *BackupStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BackupStorageLocation) DeepCopyInto(out *BackupStorageLocation) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupStorageLocation. +func (in *BackupStorageLocation) DeepCopy() *BackupStorageLocation { + if in == nil { + return nil + } + out := new(BackupStorageLocation) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *BackupStorageLocation) 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 *BackupStorageLocationList) DeepCopyInto(out *BackupStorageLocationList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]BackupStorageLocation, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupStorageLocationList. +func (in *BackupStorageLocationList) DeepCopy() *BackupStorageLocationList { + if in == nil { + return nil + } + out := new(BackupStorageLocationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *BackupStorageLocationList) 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 *BackupStorageLocationSpec) DeepCopyInto(out *BackupStorageLocationSpec) { + *out = *in + if in.Config != nil { + in, out := &in.Config, &out.Config + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + in.StorageType.DeepCopyInto(&out.StorageType) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupStorageLocationSpec. +func (in *BackupStorageLocationSpec) DeepCopy() *BackupStorageLocationSpec { + if in == nil { + return nil + } + out := new(BackupStorageLocationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BackupStorageLocationStatus) DeepCopyInto(out *BackupStorageLocationStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupStorageLocationStatus. +func (in *BackupStorageLocationStatus) DeepCopy() *BackupStorageLocationStatus { + if in == nil { + return nil + } + out := new(BackupStorageLocationStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CloudProviderConfig) DeepCopyInto(out *CloudProviderConfig) { *out = *in @@ -624,6 +725,22 @@ func (in *ExecHook) DeepCopy() *ExecHook { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectStorageLocation) DeepCopyInto(out *ObjectStorageLocation) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectStorageLocation. +func (in *ObjectStorageLocation) DeepCopy() *ObjectStorageLocation { + if in == nil { + return nil + } + out := new(ObjectStorageLocation) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ObjectStorageProviderConfig) DeepCopyInto(out *ObjectStorageProviderConfig) { *out = *in @@ -1221,6 +1338,31 @@ func (in *ScheduleStatus) DeepCopy() *ScheduleStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StorageType) DeepCopyInto(out *StorageType) { + *out = *in + if in.ObjectStorage != nil { + in, out := &in.ObjectStorage, &out.ObjectStorage + if *in == nil { + *out = nil + } else { + *out = new(ObjectStorageLocation) + **out = **in + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageType. +func (in *StorageType) DeepCopy() *StorageType { + if in == nil { + return nil + } + out := new(StorageType) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VolumeBackupInfo) DeepCopyInto(out *VolumeBackupInfo) { *out = *in