diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 755af957..20e41942 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -5,6 +5,7 @@ on: branches: - main - 'release-*' + - 'betatesting-*' pull_request: branches: '*' workflow_dispatch: diff --git a/app/deployer/connector/astra_connect.go b/app/deployer/connector/astra_connect.go index 046771ee..d499546f 100644 --- a/app/deployer/connector/astra_connect.go +++ b/app/deployer/connector/astra_connect.go @@ -56,8 +56,6 @@ func (d *AstraConnectDeployer) GetDeploymentObjects(m *v1.AstraConnector, ctx co connectorImage = fmt.Sprintf("%s/astra-connector:%s", imageRegistry, containerImage) log.Info("Using AstraConnector image", "image", connectorImage) - ref := &corev1.ConfigMapKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: common.AstraConnectName}, Key: "nats_url"} - dep := &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: common.AstraConnectName, @@ -82,30 +80,40 @@ func (d *AstraConnectDeployer) GetDeploymentObjects(m *v1.AstraConnector, ctx co Name: common.AstraConnectName, Env: []corev1.EnvVar{ { - Name: "NATS_SERVER_URL", - ValueFrom: &corev1.EnvVarSource{ConfigMapKeyRef: ref}, + Name: "LOG_LEVEL", // todo should this match what operator is + Value: "trace", }, { - Name: "LOG_LEVEL", - Value: "trace", + Name: "NATS_DISABLED", + Value: "true", + }, + { + Name: "API_TOKEN_SECRET_REF", + Value: m.Spec.Astra.TokenRef, + }, + { + Name: "ASTRA_CONTROL_URL", + Value: m.Spec.NatsSyncClient.CloudBridgeURL, + }, + { + Name: "ACCOUNT_ID", + Value: m.Spec.Astra.AccountId, + }, + { + Name: "CLOUD_ID", + Value: m.Spec.Astra.CloudId, + }, + { + Name: "CLUSTER_ID", + Value: m.Spec.Astra.ClusterId, }, { - Name: "POD_NAME", - ValueFrom: &corev1.EnvVarSource{ - FieldRef: &corev1.ObjectFieldSelector{ - APIVersion: "v1", - FieldPath: "metadata.name", - }, - }, + Name: "HOST_ALIAS_IP", + Value: m.Spec.NatsSyncClient.HostAliasIP, }, { - Name: "NAMESPACE", - ValueFrom: &corev1.EnvVarSource{ - FieldRef: &corev1.ObjectFieldSelector{ - APIVersion: "v1", - FieldPath: "metadata.namespace", - }, - }, + Name: "SKIP_TLS_VALIDATION", + Value: strconv.FormatBool(m.Spec.Astra.SkipTLSValidation), }, }, Resources: corev1.ResourceRequirements{ @@ -151,7 +159,7 @@ func (d *AstraConnectDeployer) GetConfigMapObjects(m *v1.AstraConnector, ctx con Name: common.AstraConnectName, }, Data: map[string]string{ - "nats_url": GetNatsURL(m), + //"nats_url": GetNatsURL(m), "skip_tls_validation": strconv.FormatBool(m.Spec.Astra.SkipTLSValidation), }, } diff --git a/app/deployer/connector/nats.go b/app/deployer/connector/nats.go deleted file mode 100644 index 05b24d1a..00000000 --- a/app/deployer/connector/nats.go +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (c) 2022. NetApp, Inc. All Rights Reserved. - */ - -package connector - -import ( - "context" - "fmt" - "maps" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "strings" - - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/NetApp-Polaris/astra-connector-operator/app/conf" - "github.com/NetApp-Polaris/astra-connector-operator/app/deployer/model" - - "github.com/NetApp-Polaris/astra-connector-operator/common" - - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - ctrllog "sigs.k8s.io/controller-runtime/pkg/log" - - v1 "github.com/NetApp-Polaris/astra-connector-operator/details/operator-sdk/api/v1" -) - -type NatsDeployer struct{} - -func NewNatsDeployer() model.Deployer { - return &NatsDeployer{} -} - -// GetStatefulSetObjects returns a NATS Statefulset object -func (n *NatsDeployer) GetStatefulSetObjects(m *v1.AstraConnector, ctx context.Context) ([]client.Object, controllerutil.MutateFn, error) { - log := ctrllog.FromContext(ctx) - ls := labelsForNats(common.NatsName, m.Spec.Labels) - - var replicas int32 - if m.Spec.Nats.Replicas > 2 { - replicas = m.Spec.Nats.Replicas - } else { - log.Info("Defaulting the Nats replica size", "size", common.NatsDefaultReplicas) - replicas = common.NatsDefaultReplicas - } - - var natsImage string - var imageRegistry string - var containerImage string - if m.Spec.ImageRegistry.Name != "" { - imageRegistry = m.Spec.ImageRegistry.Name - } else { - imageRegistry = common.DefaultImageRegistry - } - - if m.Spec.Nats.Image != "" { - containerImage = m.Spec.Nats.Image - } else { - containerImage = common.NatsDefaultImage - } - - natsImage = fmt.Sprintf("%s/%s", imageRegistry, containerImage) - log.Info("Using nats image", "image", natsImage) - - dep := &appsv1.StatefulSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: common.NatsName, - Namespace: m.Namespace, - Annotations: map[string]string{ - "container.seccomp.security.alpha.kubernetes.io/pod": "runtime/default", - }, - }, - Spec: appsv1.StatefulSetSpec{ - ServiceName: common.NatsClusterServiceName, - Replicas: &replicas, - Selector: &metav1.LabelSelector{ - MatchLabels: ls, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: ls, - }, - Spec: corev1.PodSpec{ - ServiceAccountName: common.NatsServiceAccountName, - Containers: []corev1.Container{{ - Image: natsImage, - Name: common.NatsName, - Ports: []corev1.ContainerPort{ - { - Name: "client", - ContainerPort: common.NatsClientPort, - }, - { - Name: "cluster", - ContainerPort: common.NatsClusterPort, - }, - { - Name: "monitor", - ContainerPort: common.NatsMonitorPort, - }, - { - Name: "metrics", - ContainerPort: common.NatsMetricsPort, - }, - }, - Command: []string{"nats-server", "--config", "/etc/nats-config/nats.conf"}, - Env: []corev1.EnvVar{ - { - Name: "CLUSTER_ADVERTISE", - Value: fmt.Sprintf("%s.nats.%s.svc", common.NatsName, m.Namespace), - }, - { - Name: "POD_NAME", - Value: common.NatsName, - }, { - Name: "POD_NAMESPACE", - Value: m.Namespace, - }, - }, - VolumeMounts: []corev1.VolumeMount{ - { - Name: common.NatsVolumeName, - MountPath: "/etc/nats-config", - }, - { - Name: "pid", - MountPath: "/var/run/nats", - }, - }, - SecurityContext: conf.GetSecurityContext(), - }}, - Volumes: []corev1.Volume{ - { - Name: common.NatsVolumeName, - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: common.NatsConfigMapName, - }, - }, - }, - }, - { - Name: "pid", - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{ - Medium: "", - }, - }, - }, - }, - }, - }, - }, - } - if m.Spec.ImageRegistry.Secret != "" { - dep.Spec.Template.Spec.ImagePullSecrets = []corev1.LocalObjectReference{ - { - Name: m.Spec.ImageRegistry.Secret, - }, - } - } - return []client.Object{dep}, model.NonMutateFn, nil -} - -// GetConfigMapObjects returns a ConfigMap object for nats -func (n *NatsDeployer) GetConfigMapObjects(m *v1.AstraConnector, ctx context.Context) ([]client.Object, controllerutil.MutateFn, error) { - log := ctrllog.FromContext(ctx) - - routes := make([]string, 0) - var index int32 - index = 0 - var replicas int32 - - // Setting the replicas to 1, things dont work with multiple replicas on GKE - // Uncomment once issue is fixed. - //if m.Spec.Nats.Replicas > 2 { - // replicas = m.Spec.Nats.Replicas - //} else { - // log.Info("Defaulting the Nats replica size", "size", common.NatsDefaultReplicas) - // replicas = common.NatsDefaultReplicas - //} - - log.Info("Defaulting the Nats replica size", "size", common.NatsDefaultReplicas) - replicas = common.NatsDefaultReplicas - - for index < replicas { - rt := fmt.Sprintf("\n nats://nats-%d.nats-cluster:%d", index, common.NatsClusterPort) - routes = append(routes, rt) - index += 1 - } - routes[len(routes)-1] += "\n " - routeConfig := strings.Join(routes, "") - - natsConf := "pid_file: \"/var/run/nats/nats.pid\"\nhttp: %d\nmax_payload: %d\n\ncluster {\n port: %d\n routes [%s]\n\n cluster_advertise: $CLUSTER_ADVERTISE\n connect_retries: 30\n}\n" - configMap := &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: m.Namespace, - Name: common.NatsConfigMapName, - }, - Data: map[string]string{ - "nats.conf": fmt.Sprintf(natsConf, common.NatsMonitorPort, common.NatsMaxPayload, common.NatsClusterPort, routeConfig), - }, - } - return []client.Object{configMap}, model.NonMutateFn, nil -} - -// GetServiceAccountObjects returns a ServiceAccount object for nats -func (n *NatsDeployer) GetServiceAccountObjects(m *v1.AstraConnector, ctx context.Context) ([]client.Object, controllerutil.MutateFn, error) { - sa := &corev1.ServiceAccount{ - ObjectMeta: metav1.ObjectMeta{ - Name: common.NatsServiceAccountName, - Namespace: m.Namespace, - Labels: labelsForNats(common.NatsName, m.Spec.Labels), - }, - } - return []client.Object{sa}, model.NonMutateFn, nil -} - -// GetServiceObjects returns a Service object for nats -func (n *NatsDeployer) GetServiceObjects(m *v1.AstraConnector, ctx context.Context) ([]client.Object, controllerutil.MutateFn, error) { - ls := labelsForNats(common.NatsName, m.Spec.Labels) - var services []client.Object - - natsService := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: common.NatsName, - Namespace: m.Namespace, - Labels: ls, - }, - Spec: corev1.ServiceSpec{ - Type: corev1.ServiceTypeClusterIP, - Ports: []corev1.ServicePort{ - { - Name: common.NatsName, - Port: common.NatsClientPort, - }, - }, - Selector: ls, - }, - } - natsClusterService := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: common.NatsClusterServiceName, - Namespace: m.Namespace, - Labels: ls, - }, - Spec: corev1.ServiceSpec{ - ClusterIP: "", - Ports: []corev1.ServicePort{ - { - Name: "client", - Port: common.NatsClientPort, - }, - { - Name: "cluster", - Port: common.NatsClusterPort, - }, - { - Name: "monitor", - Port: common.NatsMonitorPort, - }, - { - Name: "metrics", - Port: common.NatsMetricsPort, - }, - { - Name: "gateways", - Port: common.NatsGatewaysPort, - }, - }, - Selector: ls, - }, - } - services = append(services, natsService, natsClusterService) - return services, model.NonMutateFn, nil -} - -// labelsForNats returns the labels for selecting the nats resources -func labelsForNats(name string, mLabels map[string]string) map[string]string { - labels := map[string]string{"app": name} - maps.Copy(labels, mLabels) - return labels -} - -func (n *NatsDeployer) GetDeploymentObjects(m *v1.AstraConnector, ctx context.Context) ([]client.Object, controllerutil.MutateFn, error) { - return nil, model.NonMutateFn, nil -} - -func (n *NatsDeployer) GetRoleObjects(m *v1.AstraConnector, ctx context.Context) ([]client.Object, controllerutil.MutateFn, error) { - role := &rbacv1.Role{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: m.Namespace, - Name: common.NatsRoleName, - }, - Rules: []rbacv1.PolicyRule{ - { - APIGroups: []string{"security.openshift.io"}, - Resources: []string{"securitycontextconstraints"}, - Verbs: []string{"use"}, - }, - }, - } - return []client.Object{role}, model.NonMutateFn, nil -} - -func (n *NatsDeployer) GetRoleBindingObjects(m *v1.AstraConnector, ctx context.Context) ([]client.Object, controllerutil.MutateFn, error) { - roleBinding := &rbacv1.RoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: m.Namespace, - Name: common.NatsRoleBindingName, - }, - Subjects: []rbacv1.Subject{ - { - Kind: "ServiceAccount", - Name: common.NatsServiceAccountName, - }, - }, - RoleRef: rbacv1.RoleRef{ - Kind: "Role", - Name: common.NatsRoleName, - APIGroup: "rbac.authorization.k8s.io", - }, - } - return []client.Object{roleBinding}, model.NonMutateFn, nil -} - -func (n *NatsDeployer) GetClusterRoleObjects(m *v1.AstraConnector, ctx context.Context) ([]client.Object, controllerutil.MutateFn, error) { - return nil, model.NonMutateFn, nil -} - -func (n *NatsDeployer) GetClusterRoleBindingObjects(m *v1.AstraConnector, ctx context.Context) ([]client.Object, controllerutil.MutateFn, error) { - return nil, model.NonMutateFn, nil -} - -// GetNatsURL returns the nats URL -func GetNatsURL(m *v1.AstraConnector) string { - natsURL := fmt.Sprintf("nats://%s.%s:%d", common.NatsName, m.Namespace, common.NatsClientPort) - return natsURL -} diff --git a/app/deployer/connector/nats_test.go b/app/deployer/connector/nats_test.go deleted file mode 100644 index b1c7a93d..00000000 --- a/app/deployer/connector/nats_test.go +++ /dev/null @@ -1,183 +0,0 @@ -package connector_test - -import ( - "context" - "testing" - - "github.com/NetApp-Polaris/astra-connector-operator/app/deployer/connector" - "github.com/NetApp-Polaris/astra-connector-operator/common" - v1 "github.com/NetApp-Polaris/astra-connector-operator/details/operator-sdk/api/v1" - "github.com/stretchr/testify/assert" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func TestNatsGetStatefulSetObjects(t *testing.T) { - deployer := connector.NewNatsDeployer() - ctx := context.Background() - - m := &v1.AstraConnector{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-connector", - Namespace: "test-namespace", - }, - Spec: v1.AstraConnectorSpec{ - - Nats: v1.Nats{ - Replicas: 3, - Image: "test-image", - }, - - ImageRegistry: v1.ImageRegistry{ - Name: "test-registry", - Secret: "test-secret", - }, - }, - } - - objects, _, err := deployer.GetStatefulSetObjects(m, ctx) - assert.NoError(t, err) - assert.Equal(t, 1, len(objects)) - - statefulSet, ok := objects[0].(*appsv1.StatefulSet) - assert.True(t, ok) - - assert.Equal(t, common.NatsName, statefulSet.Name) - assert.Equal(t, m.Namespace, statefulSet.Namespace) - assert.Equal(t, int32(3), *statefulSet.Spec.Replicas) - assert.Equal(t, "test-registry/test-image", statefulSet.Spec.Template.Spec.Containers[0].Image) - assert.Equal(t, []corev1.LocalObjectReference{{Name: "test-secret"}}, statefulSet.Spec.Template.Spec.ImagePullSecrets) -} - -func TestNatsGetStatefulSetObjectsUseDefaults(t *testing.T) { - deployer := connector.NewNatsDeployer() - ctx := context.Background() - - m := &v1.AstraConnector{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-connector", - Namespace: "test-namespace", - }, - Spec: v1.AstraConnectorSpec{ - - Nats: v1.Nats{ - Replicas: -2, - }, - }, - } - - objects, _, err := deployer.GetStatefulSetObjects(m, ctx) - assert.NoError(t, err) - assert.Equal(t, 1, len(objects)) - - statefulSet, ok := objects[0].(*appsv1.StatefulSet) - assert.True(t, ok) - - assert.Equal(t, common.NatsName, statefulSet.Name) - assert.Equal(t, m.Namespace, statefulSet.Namespace) - assert.Equal(t, int32(1), *statefulSet.Spec.Replicas) - assert.Equal(t, "netappdownloads.jfrog.io/docker-astra-control-staging/arch30/neptune/nats:2.10.1-alpine3.18", statefulSet.Spec.Template.Spec.Containers[0].Image) - assert.Nil(t, statefulSet.Spec.Template.Spec.ImagePullSecrets) -} - -func TestNatsGetConfigMapObjects(t *testing.T) { - deployer := connector.NewNatsDeployer() - ctx := context.Background() - - m := DummyAstraConnector() - - objects, _, err := deployer.GetConfigMapObjects(&m, ctx) - assert.NoError(t, err) - assert.Equal(t, 1, len(objects)) - - configMap, ok := objects[0].(*corev1.ConfigMap) - assert.True(t, ok) - - // Todo Add assertions for the expected values in the ConfigMap object - assert.Equal(t, common.NatsConfigMapName, configMap.Name) - assert.Equal(t, m.Namespace, configMap.Namespace) - data := map[string]string{"nats.conf": "pid_file: \"/var/run/nats/nats.pid\"\nhttp: 8222\nmax_payload: 8388608\n\ncluster {\n port: 6222\n routes [\n nats://nats-0.nats-cluster:6222\n ]\n\n cluster_advertise: $CLUSTER_ADVERTISE\n connect_retries: 30\n}\n"} - assert.Equal(t, data, configMap.Data) -} - -func TestNatsGetServiceAccountObjects(t *testing.T) { - deployer := connector.NewNatsDeployer() - ctx := context.Background() - - m := DummyAstraConnector() - - objects, _, err := deployer.GetServiceAccountObjects(&m, ctx) - assert.NoError(t, err) - assert.Equal(t, 1, len(objects)) - - serviceAccount, ok := objects[0].(*corev1.ServiceAccount) - assert.True(t, ok) - - assert.Equal(t, common.NatsServiceAccountName, serviceAccount.Name) - assert.Equal(t, m.Namespace, serviceAccount.Namespace) - assert.Equal(t, map[string]string{"Label1": "Value1", "app": "nats"}, serviceAccount.Labels) -} - -func TestNatsGetServiceObjects(t *testing.T) { - deployer := connector.NewNatsDeployer() - ctx := context.Background() - - m := DummyAstraConnector() - - objects, _, err := deployer.GetServiceObjects(&m, ctx) - assert.NoError(t, err) - assert.Equal(t, 2, len(objects)) - - // test the first service which is natsService - service, ok := objects[0].(*corev1.Service) - assert.True(t, ok) - - assert.Equal(t, common.NatsName, service.Name) - assert.Equal(t, m.Namespace, service.Namespace) - assert.Equal(t, map[string]string{"Label1": "Value1", "app": "nats"}, service.Labels) - assert.Equal(t, corev1.ServiceTypeClusterIP, service.Spec.Type) - - // now test the second service nats-cluster - service, ok = objects[1].(*corev1.Service) - assert.True(t, ok) - - assert.Equal(t, common.NatsClusterServiceName, service.Name) - assert.Equal(t, m.Namespace, service.Namespace) - assert.Equal(t, map[string]string{"Label1": "Value1", "app": "nats"}, service.Labels) - -} - -// Below are all the nil objects - -func TestNatsK8sObjectsNotCreated(t *testing.T) { - deployer := connector.NewNatsDeployer() - ctx := context.Background() - - m := DummyAstraConnector() - - objects, fn, err := deployer.GetDeploymentObjects(&m, ctx) - assert.Nil(t, objects) - assert.NotNil(t, fn) - assert.Nil(t, err) - - objects, fn, err = deployer.GetRoleObjects(&m, ctx) - assert.NotNil(t, objects) - assert.NotNil(t, fn) - assert.Nil(t, err) - - objects, fn, err = deployer.GetRoleBindingObjects(&m, ctx) - assert.NotNil(t, objects) - assert.NotNil(t, fn) - assert.Nil(t, err) - - objects, fn, err = deployer.GetClusterRoleObjects(&m, ctx) - assert.Nil(t, objects) - assert.NotNil(t, fn) - assert.Nil(t, err) - - objects, fn, err = deployer.GetClusterRoleBindingObjects(&m, ctx) - assert.Nil(t, objects) - assert.NotNil(t, fn) - assert.Nil(t, err) -} diff --git a/app/deployer/connector/natssync_client.go b/app/deployer/connector/natssync_client.go deleted file mode 100644 index ba4764ae..00000000 --- a/app/deployer/connector/natssync_client.go +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (c) 2022. NetApp, Inc. All Rights Reserved. - */ - -package connector - -import ( - "context" - "errors" - "fmt" - "maps" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "strconv" - "strings" - - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" - ctrllog "sigs.k8s.io/controller-runtime/pkg/log" - - "github.com/NetApp-Polaris/astra-connector-operator/app/conf" - "github.com/NetApp-Polaris/astra-connector-operator/app/deployer/model" - "github.com/NetApp-Polaris/astra-connector-operator/app/register" - "github.com/NetApp-Polaris/astra-connector-operator/common" - v1 "github.com/NetApp-Polaris/astra-connector-operator/details/operator-sdk/api/v1" -) - -type NatsSyncClientDeployer struct{} - -func NewNatsSyncClientDeployer() model.Deployer { - return &NatsSyncClientDeployer{} -} - -// GetDeploymentObjects returns a NatsSyncClient Deployment object -func (d *NatsSyncClientDeployer) GetDeploymentObjects(m *v1.AstraConnector, ctx context.Context) ([]client.Object, controllerutil.MutateFn, error) { - log := ctrllog.FromContext(ctx) - ls := LabelsForNatsSyncClient(common.NatsSyncClientName, m.Spec.Labels) - - var imageRegistry string - var containerImage string - var natsSyncClientImage string - if m.Spec.ImageRegistry.Name != "" { - imageRegistry = m.Spec.ImageRegistry.Name - } else { - imageRegistry = common.DefaultImageRegistry - } - - if m.Spec.NatsSyncClient.Image != "" { - containerImage = m.Spec.NatsSyncClient.Image - } else { - containerImage = common.NatsSyncClientDefaultImage - } - - natsSyncClientImage = fmt.Sprintf("%s/%s", imageRegistry, containerImage) - log.Info("Using NatsSyncClient image", "image", natsSyncClientImage) - natsSyncCloudBridgeURL := register.GetAstraHostURL(m) - keyStoreURLSplit := strings.Split(common.NatsSyncClientKeystoreUrl, "://") - if len(keyStoreURLSplit) < 2 { - return nil, nil, errors.New("invalid keyStoreURLSplit provided, format - configmap:///configmap-data") - } - - dep := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: common.NatsSyncClientName, - Namespace: m.Namespace, - Annotations: map[string]string{ - "container.seccomp.security.alpha.kubernetes.io/pod": "runtime/default", - }, - }, - Spec: appsv1.DeploymentSpec{ - Replicas: &m.Spec.NatsSyncClient.Replicas, - Selector: &metav1.LabelSelector{ - MatchLabels: ls, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: ls, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{{ - Image: natsSyncClientImage, - Name: common.NatsSyncClientName, - Env: []corev1.EnvVar{ - { - Name: "NATS_SERVER_URL", - Value: GetNatsURL(m), - }, - { - Name: "CLOUD_BRIDGE_URL", - Value: natsSyncCloudBridgeURL, - }, - { - Name: "CONFIGMAP_NAME", - Value: common.NatsSyncClientConfigMapName, - }, - { - Name: "POD_NAMESPACE", - Value: m.Namespace, - }, - { - Name: "KEYSTORE_URL", - Value: common.NatsSyncClientKeystoreUrl, - }, - { - Name: "SKIP_TLS_VALIDATION", - Value: strconv.FormatBool(m.Spec.Astra.SkipTLSValidation), - }, - }, - VolumeMounts: []corev1.VolumeMount{ - { - Name: common.NatsSyncClientConfigMapVolumeName, - MountPath: keyStoreURLSplit[1], - }, - }, - SecurityContext: conf.GetSecurityContext(), - }}, - ServiceAccountName: common.NatsSyncClientConfigMapServiceAccountName, - Volumes: []corev1.Volume{ - { - Name: common.NatsSyncClientConfigMapVolumeName, - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: common.NatsSyncClientConfigMapName, - }, - }, - }, - }, - }, - }, - }, - }, - } - - if m.Spec.NatsSyncClient.HostAliasIP != "" { - hostNamesSplit := strings.Split(natsSyncCloudBridgeURL, "://") - if len(hostNamesSplit) < 2 { - return nil, nil, errors.New("invalid hostname provided, hostname format - https://hostname") - } - dep.Spec.Template.Spec.HostAliases = []corev1.HostAlias{ - { - IP: m.Spec.NatsSyncClient.HostAliasIP, - Hostnames: []string{hostNamesSplit[1]}, - }, - } - } - if m.Spec.ImageRegistry.Secret != "" { - dep.Spec.Template.Spec.ImagePullSecrets = []corev1.LocalObjectReference{ - { - Name: m.Spec.ImageRegistry.Secret, - }, - } - } - return []client.Object{dep}, model.NonMutateFn, nil -} - -// GetServiceObjects returns a NatsSyncClient Service object -func (d *NatsSyncClientDeployer) GetServiceObjects(m *v1.AstraConnector, ctx context.Context) ([]client.Object, controllerutil.MutateFn, error) { - service := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: common.NatsSyncClientName, - Namespace: m.Namespace, - Labels: map[string]string{ - "app": common.NatsSyncClientName, - }, - }, - Spec: corev1.ServiceSpec{ - Type: corev1.ServiceTypeClusterIP, - Ports: []corev1.ServicePort{ - { - Port: common.NatsSyncClientPort, - Protocol: common.NatsSyncClientProtocol, - }, - }, - Selector: map[string]string{ - "app": common.NatsSyncClientName, - }, - }, - } - return []client.Object{service}, model.NonMutateFn, nil -} - -// LabelsForNatsSyncClient returns the labels for selecting the NatsSyncClient -func LabelsForNatsSyncClient(name string, mLabels map[string]string) map[string]string { - labels := map[string]string{"app": name} - maps.Copy(labels, mLabels) - return labels -} - -// GetConfigMapObjects returns a ConfigMap object for NatsSyncClient -func (d *NatsSyncClientDeployer) GetConfigMapObjects(m *v1.AstraConnector, ctx context.Context) ([]client.Object, controllerutil.MutateFn, error) { - configMap := &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: m.Namespace, - Name: common.NatsSyncClientConfigMapName, - }, - } - return []client.Object{configMap}, model.NonMutateFn, nil -} - -// GetRoleObjects returns a ConfigMapRole object for NatsSyncClient -func (d *NatsSyncClientDeployer) GetRoleObjects(m *v1.AstraConnector, ctx context.Context) ([]client.Object, controllerutil.MutateFn, error) { - configMapRole := &rbacv1.Role{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: m.Namespace, - Name: common.NatsSyncClientConfigMapRoleName, - }, - Rules: []rbacv1.PolicyRule{ - { - APIGroups: []string{""}, - Resources: []string{"configmaps"}, - Verbs: []string{"get", "list", "patch"}, - }, - { - APIGroups: []string{"security.openshift.io"}, - Resources: []string{"securitycontextconstraints"}, - Verbs: []string{"use"}, - }, - }, - } - return []client.Object{configMapRole}, model.NonMutateFn, nil -} - -// GetRoleBindingObjects returns a NatsSyncClient ConfigMapRoleBinding object -func (d *NatsSyncClientDeployer) GetRoleBindingObjects(m *v1.AstraConnector, ctx context.Context) ([]client.Object, controllerutil.MutateFn, error) { - configMapRoleBinding := &rbacv1.RoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: m.Namespace, - Name: common.NatsSyncClientConfigMapRoleBindingName, - }, - Subjects: []rbacv1.Subject{ - { - Kind: "ServiceAccount", - Name: common.NatsSyncClientConfigMapServiceAccountName, - }, - }, - RoleRef: rbacv1.RoleRef{ - Kind: "Role", - Name: common.NatsSyncClientConfigMapRoleName, - APIGroup: "rbac.authorization.k8s.io", - }, - } - return []client.Object{configMapRoleBinding}, model.NonMutateFn, nil -} - -// GetServiceAccountObjects returns a ServiceAccount object for NatsSyncClient -func (d *NatsSyncClientDeployer) GetServiceAccountObjects(m *v1.AstraConnector, ctx context.Context) ([]client.Object, controllerutil.MutateFn, error) { - sa := &corev1.ServiceAccount{ - ObjectMeta: metav1.ObjectMeta{ - Name: common.NatsSyncClientConfigMapServiceAccountName, - Namespace: m.Namespace, - }, - } - return []client.Object{sa}, model.NonMutateFn, nil -} - -func (d *NatsSyncClientDeployer) GetStatefulSetObjects(m *v1.AstraConnector, ctx context.Context) ([]client.Object, controllerutil.MutateFn, error) { - return nil, model.NonMutateFn, nil -} - -func (d *NatsSyncClientDeployer) GetClusterRoleObjects(m *v1.AstraConnector, ctx context.Context) ([]client.Object, controllerutil.MutateFn, error) { - return nil, model.NonMutateFn, nil -} - -func (d *NatsSyncClientDeployer) GetClusterRoleBindingObjects(m *v1.AstraConnector, ctx context.Context) ([]client.Object, controllerutil.MutateFn, error) { - return nil, model.NonMutateFn, nil -} diff --git a/app/deployer/connector/natssync_client_test.go b/app/deployer/connector/natssync_client_test.go deleted file mode 100644 index 3e52f647..00000000 --- a/app/deployer/connector/natssync_client_test.go +++ /dev/null @@ -1,198 +0,0 @@ -package connector_test - -import ( - "context" - "testing" - - "github.com/NetApp-Polaris/astra-connector-operator/app/deployer/connector" - "github.com/NetApp-Polaris/astra-connector-operator/common" - v1 "github.com/NetApp-Polaris/astra-connector-operator/details/operator-sdk/api/v1" - "github.com/stretchr/testify/assert" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" -) - -func TestNatsSyncGetDeploymentObjects(t *testing.T) { - mockAstraConnector := &v1.AstraConnector{ - Spec: v1.AstraConnectorSpec{ - ImageRegistry: v1.ImageRegistry{ - Name: "test-registry", - Secret: "test-secret", - }, - NatsSyncClient: v1.NatsSyncClient{ - Image: "test-image", - Replicas: 2, - HostAliasIP: "192.168.1.1", - }, - Astra: v1.Astra{ - SkipTLSValidation: true, - }, - }, - } - - deployer := connector.NewNatsSyncClientDeployer() - - objects, _, err := deployer.GetDeploymentObjects(mockAstraConnector, context.Background()) - assert.NoError(t, err) - assert.Len(t, objects, 1) - - deployment, ok := objects[0].(*appsv1.Deployment) - assert.True(t, ok) - - assert.Equal(t, int32(2), *deployment.Spec.Replicas) - assert.Equal(t, "test-registry/test-image", deployment.Spec.Template.Spec.Containers[0].Image) - assert.Equal(t, "192.168.1.1", deployment.Spec.Template.Spec.HostAliases[0].IP) - assert.Equal(t, "test-secret", deployment.Spec.Template.Spec.ImagePullSecrets[0].Name) - assert.Equal(t, 1, len(deployment.Spec.Template.Spec.Containers)) - assert.Equal(t, "natssync-client", deployment.Spec.Template.Spec.Containers[0].Name) - -} - -func TestNatsSyncGetDeploymentObjectsDefault(t *testing.T) { - mockAstraConnector := &v1.AstraConnector{ - Spec: v1.AstraConnectorSpec{ - NatsSyncClient: v1.NatsSyncClient{ - HostAliasIP: "192.168.1.1", - Replicas: 1, - }, - Astra: v1.Astra{ - SkipTLSValidation: false, - }, - }, - } - deployer := connector.NewNatsSyncClientDeployer() - objects, _, err := deployer.GetDeploymentObjects(mockAstraConnector, context.Background()) - assert.NoError(t, err) - assert.Len(t, objects, 1) - - deployment, ok := objects[0].(*appsv1.Deployment) - assert.True(t, ok) - - assert.Equal(t, int32(1), *deployment.Spec.Replicas) - assert.Equal(t, "netappdownloads.jfrog.io/docker-astra-control-staging/arch30/neptune/natssync-client:2.2.202402012115", deployment.Spec.Template.Spec.Containers[0].Image) - assert.Equal(t, "192.168.1.1", deployment.Spec.Template.Spec.HostAliases[0].IP) - assert.Nil(t, deployment.Spec.Template.Spec.ImagePullSecrets) - // TODO add more checks -} - -func TestGetServiceObjects(t *testing.T) { - mockAstraConnector := &v1.AstraConnector{ - Spec: v1.AstraConnectorSpec{ - ImageRegistry: v1.ImageRegistry{ - Name: "test-registry", - Secret: "test-secret", - }, - NatsSyncClient: v1.NatsSyncClient{ - Image: "test-image", - Replicas: 2, - HostAliasIP: "192.168.1.1", - }, - Astra: v1.Astra{ - SkipTLSValidation: true, - }, - }, - } - - deployer := connector.NewNatsSyncClientDeployer() - objects, _, err := deployer.GetServiceObjects(mockAstraConnector, context.Background()) - assert.NoError(t, err) - assert.Len(t, objects, 1) - - service, ok := objects[0].(*corev1.Service) - assert.True(t, ok) - - assert.Equal(t, corev1.ServiceTypeClusterIP, service.Spec.Type) - assert.Equal(t, int32(8080), service.Spec.Ports[0].Port) - assert.Equal(t, corev1.Protocol("TCP"), service.Spec.Ports[0].Protocol) - assert.Equal(t, common.NatsSyncClientName, service.Spec.Selector["app"]) -} - -func TestNatsSyncGetConfigMapObjects(t *testing.T) { - mockAstraConnector := DummyAstraConnector() - deployer := connector.NewNatsSyncClientDeployer() - - objects, _, err := deployer.GetConfigMapObjects(&mockAstraConnector, context.Background()) - assert.NoError(t, err) - assert.Len(t, objects, 1) - - configMap, ok := objects[0].(*corev1.ConfigMap) - assert.True(t, ok) - - assert.Equal(t, common.NatsSyncClientConfigMapName, configMap.Name) -} - -func TestNatsSyncGetRoleObjects(t *testing.T) { - mockAstraConnector := DummyAstraConnector() - deployer := connector.NewNatsSyncClientDeployer() - - objects, _, err := deployer.GetRoleObjects(&mockAstraConnector, context.Background()) - assert.NoError(t, err) - assert.Len(t, objects, 1) - - role, ok := objects[0].(*rbacv1.Role) - assert.True(t, ok) - - assert.Equal(t, common.NatsSyncClientConfigMapRoleName, role.Name) - assert.Len(t, role.Rules, 2) - assert.Equal(t, []string{""}, role.Rules[0].APIGroups) - assert.Equal(t, []string{"configmaps"}, role.Rules[0].Resources) - assert.Equal(t, []string{"get", "list", "patch"}, role.Rules[0].Verbs) -} - -func TestGetRoleBindingObjects(t *testing.T) { - mockAstraConnector := DummyAstraConnector() - deployer := connector.NewNatsSyncClientDeployer() - objects, _, err := deployer.GetRoleBindingObjects(&mockAstraConnector, context.Background()) - assert.NoError(t, err) - - assert.Len(t, objects, 1) - - roleBinding, ok := objects[0].(*rbacv1.RoleBinding) - assert.True(t, ok) - - assert.Equal(t, common.NatsSyncClientConfigMapRoleBindingName, roleBinding.Name) - assert.Len(t, roleBinding.Subjects, 1) - assert.Equal(t, "ServiceAccount", roleBinding.Subjects[0].Kind) - assert.Equal(t, common.NatsSyncClientConfigMapServiceAccountName, roleBinding.Subjects[0].Name) - assert.Equal(t, "Role", roleBinding.RoleRef.Kind) - assert.Equal(t, common.NatsSyncClientConfigMapRoleName, roleBinding.RoleRef.Name) - assert.Equal(t, "rbac.authorization.k8s.io", roleBinding.RoleRef.APIGroup) -} - -func TestNatsSyncGetServiceAccountObjects(t *testing.T) { - // Create a mock AstraConnector object - m := DummyAstraConnector() - deployer := connector.NewNatsSyncClientDeployer() - objects, _, err := deployer.GetServiceAccountObjects(&m, context.Background()) - assert.NoError(t, err) - - assert.Len(t, objects, 1) - serviceAccount, ok := objects[0].(*corev1.ServiceAccount) - assert.True(t, ok) - - assert.Equal(t, common.NatsSyncClientConfigMapServiceAccountName, serviceAccount.Name) -} - -// Below are all the nil objects -func TestNatsSyncK8sObjectsNotCreated(t *testing.T) { - deployer := connector.NewNatsSyncClientDeployer() - ctx := context.Background() - - m := DummyAstraConnector() - - objects, fn, err := deployer.GetStatefulSetObjects(&m, ctx) - assert.Nil(t, objects) - assert.NotNil(t, fn) - assert.Nil(t, err) - - objects, fn, err = deployer.GetClusterRoleObjects(&m, ctx) - assert.Nil(t, objects) - assert.NotNil(t, fn) - assert.Nil(t, err) - - objects, fn, err = deployer.GetClusterRoleBindingObjects(&m, ctx) - assert.Nil(t, objects) - assert.NotNil(t, fn) - assert.Nil(t, err) -} diff --git a/astraconnector_operator.yaml b/astraconnector_operator.yaml new file mode 100644 index 00000000..8b480d89 --- /dev/null +++ b/astraconnector_operator.yaml @@ -0,0 +1,6716 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/component: manager + app.kubernetes.io/created-by: neptune + app.kubernetes.io/instance: system + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: namespace + app.kubernetes.io/part-of: neptune + control-plane: controller-manager + name: astra-connector +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: applications.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: Application + listKind: ApplicationList + plural: applications + singular: application + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: Application is the Schema for the applications API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ApplicationSpec defines the desired state of Application + properties: + includedClusterScopedResources: + description: IncludedClusterScopedResources is a list of cluster-scoped resource types to be included. + items: + properties: + groupVersionKind: + description: GroupVersionKind unambiguously identifies a kind + properties: + group: + type: string + kind: + type: string + version: + type: string + type: object + labelSelector: + description: A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: array + includedNamespaces: + description: IncludedNamespaces is a slice of namespaceSelectors to include in our app definition. + items: + properties: + labelSelector: + description: A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespace: + type: string + required: + - namespace + type: object + type: array + required: + - includedNamespaces + type: object + status: + description: ApplicationStatus defines the observed state of Application + properties: + conditions: + description: Each Condition contains details for one aspect of the current state of the Application. + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + protectionState: + description: 'ProtectionState determines protection state of the app based upon different parameters The current logic for protectionState is as follows: Fully Protected: someScheduleIsActive && hasScheduleWithSuccessfulLastBackup Partially Protected: someScheduleIsActive || someSuccessfulBackupExists || someSuccessfulSnapshotExists Not Protected: default' + type: string + protectionStateDetails: + description: ProtectionStateDetails add additional information regarding the protection state of an application + items: + type: string + type: array + required: + - conditions + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: appmirrorrelationships.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: AppMirrorRelationship + listKind: AppMirrorRelationshipList + plural: appmirrorrelationships + shortNames: + - amr + singular: appmirrorrelationship + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.state + name: State + type: string + - jsonPath: .status.error + name: Error + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: AppMirrorRelationship is the Schema for the appmirrorrelationships API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: AppMirrorRelationshipSpec defines the desired state of AppMirrorRelationship + properties: + applicationRef: + description: ApplicationRef is the name of the Application + type: string + desiredState: + description: DesiredState is the desired state of the AppMirrorRelationship + enum: + - established + - promoted + type: string + destinationAppVaultRef: + description: DestinationAppVaultRef is the name of the destination AppVault + type: string + namespaceMapping: + description: NamespaceMapping is the mapping between source namespace to target namespace + items: + properties: + destination: + description: Destination namespace where the single resource will be cloned into + type: string + source: + description: Source namespace of a single resource in the collection + type: string + required: + - destination + - source + type: object + type: array + promotedSnapshot: + description: PromotedSnapshot is the snapshot name to use during a planned fail over + type: string + recurrenceRule: + description: RecurrenceRule is a string containing an RFC-5545 Section 3.8.5.3. Recurrence Rule. For the DTSTART parameter, only UTC timestamps (denoted by the "Z" suffix) are supported, and only timestamps before the current time are supported. For the RECUR rule parts, "FREQ" and "INTERVAL" are the only rule parts supported. For the FREQ rule part, "MINUTELY" and "HOURLY" are the only values supported. + type: string + sourceAppVaultRef: + description: SourceAppVaultRef is the name of the source AppVault + type: string + sourceSnapshotsPath: + description: SourceSnapshotsPath is the name of the source app snapshots path + type: string + storageClassName: + description: StorageClassName is the name of the StorageClass to use when creating new PVCs + type: string + required: + - applicationRef + - desiredState + - destinationAppVaultRef + - recurrenceRule + - sourceAppVaultRef + - sourceSnapshotsPath + type: object + status: + description: AppMirrorRelationshipStatus defines the observed state of AppMirrorRelationship + properties: + conditions: + description: Each Condition contains details for one aspect of the current state of the AppMirrorRelationship + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + error: + description: Error indicates the most recent error that has occurred. The error may not be permanent, so progress may continue after temporarily seeing an error. + type: string + state: + description: State indicates the current state of the AppMirrorRelationship + type: string + required: + - conditions + - state + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: appmirrorupdates.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: AppMirrorUpdate + listKind: AppMirrorUpdateList + plural: appmirrorupdates + shortNames: + - amu + singular: appmirrorupdate + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.state + name: State + type: string + - jsonPath: .status.error + name: Error + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: AppMirrorUpdate is the Schema for the appmirrorupdates API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: AppMirrorUpdateSpec defines the desired state of AppMirrorUpdate + properties: + appMirrorRelationshipRef: + description: Name of the owning AppMirrorRelationship + minLength: 1 + type: string + applicationRef: + description: Name of the Application + minLength: 1 + type: string + destinationAppVaultRef: + description: Name of the DestinationAppVault + minLength: 1 + type: string + sourceAppArchivePath: + description: Name of the source app archive path + minLength: 1 + type: string + sourceAppVaultRef: + description: Name of the SourceAppVault + minLength: 1 + type: string + required: + - appMirrorRelationshipRef + - applicationRef + - destinationAppVaultRef + - sourceAppArchivePath + - sourceAppVaultRef + type: object + status: + description: AppMirrorUpdateStatus defines the observed state of AppMirrorUpdate + properties: + appArchivePath: + description: AppArchivePath is the path where the snapshot was archived in the destination AppVault. + type: string + completionTimestamp: + description: CompletionTimestamp records the time the AppMirrorUpdate completed. The server's time is used for CompletionTimestamps + format: date-time + nullable: true + type: string + conditions: + description: Each Condition contains details for one aspect of the current state of the AppMirrorUpdate. + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + destinationVolumes: + description: Each AppMirrorUpdateDestinationVolume contains details for one destination volume that the AppMirrorUpdate targets. + items: + properties: + destinationPVC: + description: DestinationPVC holds the namespace and name for the destination PVC + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + destinationStorageClass: + description: DestinationStorageClass holds the storage class for the destination PVC + type: string + destinationTAMU: + description: DestinationTAMU holds the namespace and name for the TAMUs created at the destination site + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + destinationTMR: + description: DestinationTMR holds the namespace and name for the destination TMR + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + newlyReplicated: + description: NewlyReplicated will be set to true if the destination PVC did not already exist + type: boolean + sourcePVC: + description: SourcePVC holds the namespace and name for the source PVC + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + required: + - destinationPVC + - destinationTMR + - newlyReplicated + - sourcePVC + type: object + type: array + error: + description: Error indicates the most recent error that has occurred. The error may not be permanent, so progress may continue after temporarily seeing an error. + type: string + state: + description: State indicates a high level summary of the AppMirrorUpdate's state + type: string + required: + - state + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: appvaults.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: AppVault + listKind: AppVaultList + plural: appvaults + singular: appvault + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: AppVault is the Schema for the appvaults API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: AppVaultSpec defines the desired state of AppVault + properties: + prefix: + description: Prefix is an optional path which will be prefixed to the names of all entities stored in the vault. + type: string + providerConfig: + additionalProperties: + type: string + description: ProviderConfig stores the configuration necessary to access the AppVault using the specified provider. + type: object + providerCredentials: + additionalProperties: + properties: + valueFromSecret: + description: ValueFromSecret indicates that the credential value should come from a secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: Name of the secret containing the value for this field. Must be in the same namespace. + type: string + required: + - key + - name + type: object + required: + - valueFromSecret + type: object + description: ProviderCredentials stores references to any credentials required to access the AppVault using the specified provider. + type: object + providerType: + description: ProviderType determines what provides the backup, e.g. S3 or FileSystem + type: string + required: + - providerConfig + - providerType + type: object + status: + description: AppVaultStatus defines the observed state of AppVault + properties: + error: + type: string + state: + type: string + uid: + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: autosupportbundles.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: AutoSupportBundle + listKind: AutoSupportBundleList + plural: autosupportbundles + singular: autosupportbundle + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: AutoSupportBundle is the Schema for the autosupportbundles API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: AutoSupportBundleSpec defines the desired state of AutoSupportBundle + properties: + dateWindowStart: + description: DateWindowStart is a timestamp indicating the start time of the AutoSupport bundle data collection window. Defaults to 24 hours ago if not specified. + format: date-time + type: string + triggerType: + description: TriggerType indicates how the AutoSupport bundle was triggered + enum: + - Manual + - Scheduled + type: string + uploadEnabled: + description: UploadEnabled is a boolean that indicates if AutoSupport bundle should be uploaded or not after generation. Defaults to false if not specified. + type: boolean + required: + - triggerType + type: object + status: + description: AutoSupportBundleStatus defines the observed state of AutoSupportBundle + properties: + bundleCompletionTimestamp: + description: BundleCompletionTimestamp The time that the ASUP generation and upload (if enabled) completed + format: date-time + type: string + bundleFile: + description: BundleFile is the location and filename of the bundle in the ASUP job pod + type: string + bundleKubectlCpCommand: + description: BundleKubectlCpCommand is the kubectl cp command for copying the bundle from the job pod + type: string + bundleNamespace: + description: BundleNamespace is the namespace of the ASUP job pod + type: string + bundlePodName: + description: BundlePodName is the pod where the bundle is located + type: string + completionTimestamp: + description: CompletionTimestamp The time the ASUP job completed + format: date-time + type: string + conditions: + description: Each Condition contains details for one aspect of the current state of the autosupportbundle. + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + error: + description: Error indicates the most recent error that has occurred. The error may not be permanent, so progress may continue after temporarily seeing an error. + type: string + generationState: + description: GenerationState is the current state of the ASUP bundle creation + enum: + - AlreadyInProgress + - Pending + - Running + - Completed + - Partial + - Failed + type: string + state: + description: State indicates a high level summary of the autosupportbundle's state + type: string + uploadState: + description: UploadState is the current state of the ASUP bundle upload + enum: + - Pending + - Blocked + - Running + - Completed + - Failed + - Disabled + type: string + required: + - conditions + - state + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: autosupportbundleschedules.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: AutoSupportBundleSchedule + listKind: AutoSupportBundleScheduleList + plural: autosupportbundleschedules + singular: autosupportbundleschedule + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: AutoSupportBundleSchedule is the Schema for the autosupportbundleschedules API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: AutoSupportBundleScheduleSpec defines the desired state of AutoSupportBundleSchedule + properties: + enabled: + description: Enabled determines if scheduled AutoSupportBundles are run or not + type: boolean + type: object + status: + description: AutoSupportBundleScheduleStatus defines the observed state of AutoSupportBundleSchedule + properties: + nextScheduledTimestamp: + description: NextScheduledTimestamp The time to run the next scheduled ASUP + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: backupinplacerestores.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: BackupInplaceRestore + listKind: BackupInplaceRestoreList + plural: backupinplacerestores + singular: backupinplacerestore + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.state + name: State + type: string + - jsonPath: .status.error + name: Error + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: BackupInplaceRestore is the Schema for the backupinplacerestores API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: BackupInplaceRestoreSpec defines the desired state of BackupInplaceRestore + properties: + appArchivePath: + description: AppArchivePath is the path inside AppVault where the snapshot contents are stored. + type: string + appVaultRef: + description: AppVaultRef is the reference to the AppVault where the snapshot contents are stored. + type: string + namespaceMapping: + description: NamespaceMapping is the mapping between source namespace to target namespace + items: + properties: + destination: + description: Destination namespace where the single resource will be cloned into + type: string + source: + description: Source namespace of a single resource in the collection + type: string + required: + - destination + - source + type: object + type: array + resourceFilter: + description: ResourceFilter should be populated by the user if only certain resources must be restored in the target namespace + properties: + resourceMatchers: + description: ResourceMatchers is a list of matchers where each matcher matches one or more resources + items: + properties: + group: + description: Group of the kubernetes resource that has to be matched + type: string + kind: + description: Kind of the kubernetes resource that has to be matched + type: string + labelSelectors: + description: LabelSelectors is used to match resource(s) based on the metadata.labels field of the kubernetes resource + items: + type: string + type: array + names: + description: Names kubernetes metadata.name field of the resource(s) that must be matched. + items: + type: string + type: array + namespaces: + description: Namespaces kubernetes metadata.namespace field of the resource(s) that must be matched. + items: + type: string + type: array + version: + description: Version of the kubernetes resource that has to be matched. + type: string + type: object + type: array + resourceSelectionCriteria: + description: ResourceSelectionCriteria used to determine if the resources matching the provided resources matchers should be included into the collection or excluded from the collection. + enum: + - include + - exclude + type: string + type: object + type: object + status: + description: BackupInplaceRestoreStatus defines the observed state of BackupInplaceRestore + properties: + completionTimestamp: + description: CompletionTimestamp records the time the Restore completed. The server's time is used for CompletionTimestamps + format: date-time + nullable: true + type: string + conditions: + description: Condition contains details for one aspect of the current state of this BackupInplaceRestore + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + error: + description: Error indicates the most recent error that has occurred. The error may not be permanent, so progress may continue after temporarily seeing an error. + type: string + state: + description: State indicates a high level summary of the BackupInplaceRestores's state + type: string + required: + - state + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: backuprestores.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: BackupRestore + listKind: BackupRestoreList + plural: backuprestores + singular: backuprestore + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.state + name: State + type: string + - jsonPath: .status.error + name: Error + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: BackupRestore is the Schema for the backuprestores API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: BackupRestoreSpec defines the desired state of BackupRestore + properties: + appArchivePath: + description: AppArchivePath is the path inside AppVault where the backup contents are stored. + type: string + appVaultRef: + description: AppVaultRef is the reference to the AppVault where the backup contents are stored. + type: string + namespaceMapping: + description: NamespaceMapping is the mapping between source namespace to target namespace + items: + properties: + destination: + description: Destination namespace where the single resource will be cloned into + type: string + source: + description: Source namespace of a single resource in the collection + type: string + required: + - destination + - source + type: object + type: array + resourceFilter: + description: ResourceFilter should be populated by the user if only certain resources must be restored in the target namespace + properties: + resourceMatchers: + description: ResourceMatchers is a list of matchers where each matcher matches one or more resources + items: + properties: + group: + description: Group of the kubernetes resource that has to be matched + type: string + kind: + description: Kind of the kubernetes resource that has to be matched + type: string + labelSelectors: + description: LabelSelectors is used to match resource(s) based on the metadata.labels field of the kubernetes resource + items: + type: string + type: array + names: + description: Names kubernetes metadata.name field of the resource(s) that must be matched. + items: + type: string + type: array + namespaces: + description: Namespaces kubernetes metadata.namespace field of the resource(s) that must be matched. + items: + type: string + type: array + version: + description: Version of the kubernetes resource that has to be matched. + type: string + type: object + type: array + resourceSelectionCriteria: + description: ResourceSelectionCriteria used to determine if the resources matching the provided resources matchers should be included into the collection or excluded from the collection. + enum: + - include + - exclude + type: string + type: object + storageClassMapping: + description: StorageClassMapping defines a mapping from a storageClass present in the source application to the assignment in the restored application (clone) + items: + properties: + destination: + description: Destination storageClass that is assigned to the same PVC in the cloned/restored application + type: string + source: + description: Source storageClass that is assigned to one of the PVCs in the source application + type: string + required: + - destination + - source + type: object + type: array + required: + - appArchivePath + - appVaultRef + - namespaceMapping + type: object + status: + description: BackupRestoreStatus defines the observed state of BackupRestore + properties: + completionTimestamp: + description: CompletionTimestamp records the time the Restore completed. The server's time is used for CompletionTimestamps + format: date-time + nullable: true + type: string + conditions: + description: Each Condition contains details for one aspect of the current state of the Backup Restore. + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + error: + description: Error indicates the most recent error that has occurred. The error may not be permanent, so progress may continue after temporarily seeing an error. + type: string + state: + description: 'INSERT ADDITIONAL STATUS FIELD - define observed state of cluster Important: Run "make" to regenerate code after modifying this file State indicates a high level summary of the Backup Restore''s state' + type: string + required: + - conditions + - state + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: backups.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: Backup + listKind: BackupList + plural: backups + singular: backup + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.state + name: State + type: string + - jsonPath: .status.error + name: Error + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: Backup is the Schema for the backups API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: BackupSpec defines the desired state of Backup + properties: + appVaultRef: + description: Name of the AppVault to use as the target of the backup + type: string + applicationRef: + description: Name of the Application to back up + type: string + reclaimPolicy: + description: ReclaimPolicy defines what happens to a backup when released from its claim. Valid options are Retain, Delete (default). + type: string + snapshotRef: + description: Name of the Snapshot to use as the source of the Backup. If not provided, a temporary Snapshot will be created and backed up + type: string + required: + - appVaultRef + - applicationRef + type: object + status: + description: BackupStatus defines the observed state of Backup + properties: + appArchivePath: + description: AppArchivePath is the path where the backup was archived in the AppVault. + type: string + completionTimestamp: + description: CompletionTimestamp records the time the Backup completed. The server's time is used for CompletionTimestamps + format: date-time + nullable: true + type: string + conditions: + description: Each Condition contains details for one aspect of the current state of the Backup. + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + error: + description: Error indicates the most recent error that has occurred. The error may not be permanent, so progress may continue after temporarily seeing an error. + type: string + postBackupExecHooksRunResults: + description: PostBackupExecHooksRunResults contains the results of executing hooks during the post/backup stage/action + items: + properties: + completionTimestamp: + description: CompletionTimestamp the time the exec hook run was finished regardless of failures + format: date-time + type: string + containerImage: + description: ContainerImage the image of the container the exec hook is run on + type: string + containerName: + description: ContainerName the name of the container the exec hook is run on + type: string + execHookRef: + description: ExecHookRef reference to the ExecHook being run + type: string + execHookUID: + description: ExecHookUID UID of the ExecHook being run + type: string + failures: + description: Failures list of failures that may occur when attempting to run the exec hook + items: + description: Failure - most of this data is used for posting events and notifications + properties: + error: + description: Error if a golang error was produced during the process of running an exec hook + type: string + exitCode: + description: ExitCode if the script was executed but returned a non-zero exit code it is captured here. Note that customers can define their own exit code with special meanings to them + type: integer + isExecError: + description: IsExecError this indicates that the script itself returned an error vs an error in other parts of the process such as copying the script onto the container + type: boolean + isTimeout: + description: IsTimeout indicates that the exec hook took too long and was abandoned, this is parity with Astra + type: boolean + stderr: + description: Stderr the stderr captured when executing the script + type: string + timeoutMinutes: + description: TimeoutMinutes indicates the amount of time that was given to the exec hook to run. In astra it is used for Activity/Event/Notification messages + type: integer + required: + - isExecError + - isTimeout + type: object + type: array + jobName: + description: JobName name of the job created to run an execution hook + type: string + namespace: + description: Namespace the namespace from the target application where the container is located + type: string + podName: + description: PodName the name of the pod where the exec hook will be run + type: string + podUID: + description: PodUID the uid of the pod where the exec hook will be run + type: string + startTimestamp: + description: StartedTimestamp the time the exec hook started running + format: date-time + type: string + required: + - containerImage + - containerName + - execHookRef + - execHookUID + - namespace + - podName + - podUID + type: object + type: array + postSnapshotExecHooksRunResults: + description: PostSnapshotExecHooksRunResults contains the results of executing hooks during the post/snapshot stage/action + items: + properties: + completionTimestamp: + description: CompletionTimestamp the time the exec hook run was finished regardless of failures + format: date-time + type: string + containerImage: + description: ContainerImage the image of the container the exec hook is run on + type: string + containerName: + description: ContainerName the name of the container the exec hook is run on + type: string + execHookRef: + description: ExecHookRef reference to the ExecHook being run + type: string + execHookUID: + description: ExecHookUID UID of the ExecHook being run + type: string + failures: + description: Failures list of failures that may occur when attempting to run the exec hook + items: + description: Failure - most of this data is used for posting events and notifications + properties: + error: + description: Error if a golang error was produced during the process of running an exec hook + type: string + exitCode: + description: ExitCode if the script was executed but returned a non-zero exit code it is captured here. Note that customers can define their own exit code with special meanings to them + type: integer + isExecError: + description: IsExecError this indicates that the script itself returned an error vs an error in other parts of the process such as copying the script onto the container + type: boolean + isTimeout: + description: IsTimeout indicates that the exec hook took too long and was abandoned, this is parity with Astra + type: boolean + stderr: + description: Stderr the stderr captured when executing the script + type: string + timeoutMinutes: + description: TimeoutMinutes indicates the amount of time that was given to the exec hook to run. In astra it is used for Activity/Event/Notification messages + type: integer + required: + - isExecError + - isTimeout + type: object + type: array + jobName: + description: JobName name of the job created to run an execution hook + type: string + namespace: + description: Namespace the namespace from the target application where the container is located + type: string + podName: + description: PodName the name of the pod where the exec hook will be run + type: string + podUID: + description: PodUID the uid of the pod where the exec hook will be run + type: string + startTimestamp: + description: StartedTimestamp the time the exec hook started running + format: date-time + type: string + required: + - containerImage + - containerName + - execHookRef + - execHookUID + - namespace + - podName + - podUID + type: object + type: array + preBackupExecHooksRunResults: + description: PreBackupExecHooksRunResults contains the results of executing hooks during the pre/backup stage/action + items: + properties: + completionTimestamp: + description: CompletionTimestamp the time the exec hook run was finished regardless of failures + format: date-time + type: string + containerImage: + description: ContainerImage the image of the container the exec hook is run on + type: string + containerName: + description: ContainerName the name of the container the exec hook is run on + type: string + execHookRef: + description: ExecHookRef reference to the ExecHook being run + type: string + execHookUID: + description: ExecHookUID UID of the ExecHook being run + type: string + failures: + description: Failures list of failures that may occur when attempting to run the exec hook + items: + description: Failure - most of this data is used for posting events and notifications + properties: + error: + description: Error if a golang error was produced during the process of running an exec hook + type: string + exitCode: + description: ExitCode if the script was executed but returned a non-zero exit code it is captured here. Note that customers can define their own exit code with special meanings to them + type: integer + isExecError: + description: IsExecError this indicates that the script itself returned an error vs an error in other parts of the process such as copying the script onto the container + type: boolean + isTimeout: + description: IsTimeout indicates that the exec hook took too long and was abandoned, this is parity with Astra + type: boolean + stderr: + description: Stderr the stderr captured when executing the script + type: string + timeoutMinutes: + description: TimeoutMinutes indicates the amount of time that was given to the exec hook to run. In astra it is used for Activity/Event/Notification messages + type: integer + required: + - isExecError + - isTimeout + type: object + type: array + jobName: + description: JobName name of the job created to run an execution hook + type: string + namespace: + description: Namespace the namespace from the target application where the container is located + type: string + podName: + description: PodName the name of the pod where the exec hook will be run + type: string + podUID: + description: PodUID the uid of the pod where the exec hook will be run + type: string + startTimestamp: + description: StartedTimestamp the time the exec hook started running + format: date-time + type: string + required: + - containerImage + - containerName + - execHookRef + - execHookUID + - namespace + - podName + - podUID + type: object + type: array + preSnapshotExecHooksRunResults: + description: PreSnapshotExecHooksRunResults contains the results of executing hooks during the pre/snapshot stage/action + items: + properties: + completionTimestamp: + description: CompletionTimestamp the time the exec hook run was finished regardless of failures + format: date-time + type: string + containerImage: + description: ContainerImage the image of the container the exec hook is run on + type: string + containerName: + description: ContainerName the name of the container the exec hook is run on + type: string + execHookRef: + description: ExecHookRef reference to the ExecHook being run + type: string + execHookUID: + description: ExecHookUID UID of the ExecHook being run + type: string + failures: + description: Failures list of failures that may occur when attempting to run the exec hook + items: + description: Failure - most of this data is used for posting events and notifications + properties: + error: + description: Error if a golang error was produced during the process of running an exec hook + type: string + exitCode: + description: ExitCode if the script was executed but returned a non-zero exit code it is captured here. Note that customers can define their own exit code with special meanings to them + type: integer + isExecError: + description: IsExecError this indicates that the script itself returned an error vs an error in other parts of the process such as copying the script onto the container + type: boolean + isTimeout: + description: IsTimeout indicates that the exec hook took too long and was abandoned, this is parity with Astra + type: boolean + stderr: + description: Stderr the stderr captured when executing the script + type: string + timeoutMinutes: + description: TimeoutMinutes indicates the amount of time that was given to the exec hook to run. In astra it is used for Activity/Event/Notification messages + type: integer + required: + - isExecError + - isTimeout + type: object + type: array + jobName: + description: JobName name of the job created to run an execution hook + type: string + namespace: + description: Namespace the namespace from the target application where the container is located + type: string + podName: + description: PodName the name of the pod where the exec hook will be run + type: string + podUID: + description: PodUID the uid of the pod where the exec hook will be run + type: string + startTimestamp: + description: StartedTimestamp the time the exec hook started running + format: date-time + type: string + required: + - containerImage + - containerName + - execHookRef + - execHookUID + - namespace + - podName + - podUID + type: object + type: array + progress: + description: Used to internally track progress through the backup + properties: + volumeBackups: + description: Progress of the individual volume backups, one for each VolumeSnapshot in the source Snapshot + items: + properties: + completionTimestamp: + description: CompletionTimestamp records the time the volume backup completed. The server's time is used for CompletionTimestamps + format: date-time + nullable: true + type: string + pvcUid: + description: k8s UID of the source app PVC + type: string + resticRepositoryPath: + description: Restic repository location (specified in the same format as the "-r" option of the restic CLI) + type: string + resticSnapshotID: + description: ID of the Restic snapshot created to represent this backup + type: string + resticVolumeBackupCompleted: + description: Set to true when the ResticVolumeBackup has completed successfully + type: boolean + resticVolumeBackupCreated: + description: Set to true when the ResticVolumeBackup for the VolumeSnapshot has been created + type: boolean + sourceVolumeSnapshot: + description: Namespaced name of the source VolumeSnapshot to be backed up + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + volumeSnapshotContentCopyName: + description: Name of the temporary copy of the VolumeSnapshotContent + type: string + volumeSnapshotCopied: + description: Set to true when the temporary copies of the VolumeSnapshot and VolumeSnapshotContent have been created + type: boolean + volumeSnapshotCopyDeleted: + description: Set to true when the temporary copies of the VolumeSnapshot and VolumeSnapshotContent have been deleted + type: boolean + volumeSnapshotCopyName: + description: Name of the temporary copy of the VolumeSnapshot + type: string + volumeSnapshotCopyReadyToUse: + description: Set to true when the temporary copy of the VolumeSnapshot is ready to use + type: boolean + required: + - resticVolumeBackupCompleted + - resticVolumeBackupCreated + - sourceVolumeSnapshot + - volumeSnapshotContentCopyName + - volumeSnapshotCopied + - volumeSnapshotCopyDeleted + - volumeSnapshotCopyName + - volumeSnapshotCopyReadyToUse + type: object + type: array + type: object + sourceSnapshotName: + description: Name of the snapshot to used for this backup (will be either the SnapshotRef if provided in the Backup spec, or a temporary snapshot name if SnapshotRef was not provided) + type: string + state: + description: State indicates a high level summary of the Backup's state + type: string + required: + - conditions + - progress + - state + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: exechooks.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: ExecHook + listKind: ExecHookList + plural: exechooks + singular: exechook + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ExecHook is the Schema for the exechooks API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: "ExecHookSpec defines the desired state of ExecHook It represents the ExecutionHook defined in Astra Nautilus. It is associated with one application. Its purpose is to define the hook source, arguments and what to execute the script against. It contains criteria to match against application containers It can be enabled/disabled It contains parameters to pass into the script In Nautilus the script (hook source) is stored separately from the execution hook but in Neptune these are combined \n This will require the sync process to update all Execution Hooks when the Hook Source is updated in Nautilus This will prevent a direct user of Neptune from having re-usable scripts" + properties: + action: + description: 'Action String that indicates which action the execution hook will run for, assuming the match criteria are met. values: snapshot, backup, restore and failover' + enum: + - snapshot + - backup + - restore + - failover + type: string + applicationRef: + description: ApplicationRef is the reference to the Application this exec hook is associated with + type: string + arguments: + description: Arguments Array of strings for the arguments to pass to the exec hook source when executing on the container + items: + type: string + maxItems: 127 + minItems: 0 + type: array + enabled: + default: true + description: Enabled allows the execution hook to be enabled or disabled. Disabled execution hooks are not executed regardless of matching criteria. + type: boolean + hookSource: + description: HookSource Base64 encoded string containing the source of a shell script which will be executed on matching containers + maxLength: 131072 + minLength: 0 + type: string + matchingCriteria: + description: MatchingCriteria Array describing the match criteria for the execution hook to match against containers the hook will execute on + items: + properties: + type: + description: Type indicates the matching criteria type specified by MatchingCriteriaType + type: string + value: + description: Value string containing a regex to match for the given match. Uses RE2 syntax described at https://golang.org/s/re2syntax + type: string + type: object + maxItems: 10 + minItems: 0 + type: array + stage: + description: 'Stage String that indicates at what stage during the action the hook will be executed, values: pre and post' + enum: + - pre + - post + type: string + timeout: + default: 25 + description: Timeout int that defines the max time in minutes an execution hook will be allowed to run. Min is 1 minute. Defaults to 25 min if not specified + minimum: 1 + type: integer + required: + - action + - applicationRef + - enabled + - hookSource + - stage + type: object + status: + description: ExecHookStatus defines the observed state of ExecHook + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: exechooksruns.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: ExecHooksRun + listKind: ExecHooksRunList + plural: exechooksruns + singular: exechooksrun + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.state + name: State + type: string + - jsonPath: .status.error + name: Error + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ExecHooksRun is the Schema for the exechooksruns API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ExecHooksRunSpec defines the desired state of ExecHooksRun The ExecHooksRun exists to provide the results of running ExecHooks Action current operation being performed, possible values are snapshot, backup, restore and failover Stage the location within the action being performed, possible values are pre and post It will be responsible for getting all ExecHooks matching the application, stage and action It will be responsible for filtering the containers based on each ExecHook's matching criteria It will create an exec hook job for each matching container It will contain the results of each execution + properties: + action: + description: Action The current action to run execution hooks for + enum: + - snapshot + - backup + - restore + - failover + type: string + appArchivePath: + description: AppArchivePath The specific location in AppVault of the resourcebackup to retrieve pods and containers from + type: string + appVaultRef: + description: AppVaultRef The location of the resourcebackup to retrieve pods and containers from + type: string + applicationRef: + description: ApplicationRef is the reference to the Application to execute hooks against + type: string + completionTimeout: + description: CompletionTimeout specifies the time to wait for the entire ExecHooksRun to complete before returning timeout error. The default value is 30 minutes. + type: string + resourceFilter: + description: ResourceFilter Should be populated by the user, if only certain resources should be considered for executing hooks, which is often useful when doing a selective restore + properties: + resourceMatchers: + description: ResourceMatchers is a list of matchers where each matcher matches one or more resources + items: + properties: + group: + description: Group of the kubernetes resource that has to be matched + type: string + kind: + description: Kind of the kubernetes resource that has to be matched + type: string + labelSelectors: + description: LabelSelectors is used to match resource(s) based on the metadata.labels field of the kubernetes resource + items: + type: string + type: array + names: + description: Names kubernetes metadata.name field of the resource(s) that must be matched. + items: + type: string + type: array + namespaces: + description: Namespaces kubernetes metadata.namespace field of the resource(s) that must be matched. + items: + type: string + type: array + version: + description: Version of the kubernetes resource that has to be matched. + type: string + type: object + type: array + resourceSelectionCriteria: + description: ResourceSelectionCriteria used to determine if the resources matching the provided resources matchers should be included into the collection or excluded from the collection. + enum: + - include + - exclude + type: string + type: object + stage: + description: Stage The current stage to run execution hooks for + enum: + - pre + - post + type: string + required: + - action + - appArchivePath + - appVaultRef + - applicationRef + - stage + type: object + status: + description: ExecHooksRunStatus defines the observed state of ExecHooksRun + properties: + completionTimestamp: + description: CompletionTimestamp The time that the ExecutionHooksRun completed + format: date-time + type: string + conditions: + description: Each Condition contains details for one aspect of the current state of the ExecHooksRun. + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + error: + description: Error indicates the most recent error that has occurred. The error may not be permanent, so progress may continue after temporarily seeing an error. + type: string + matchingContainers: + description: MatchingContainers The status of each ExecHook that was run on each container + items: + properties: + completionTimestamp: + description: CompletionTimestamp the time the exec hook run was finished regardless of failures + format: date-time + type: string + containerImage: + description: ContainerImage the image of the container the exec hook is run on + type: string + containerName: + description: ContainerName the name of the container the exec hook is run on + type: string + execHookRef: + description: ExecHookRef reference to the ExecHook being run + type: string + execHookUID: + description: ExecHookUID UID of the ExecHook being run + type: string + failures: + description: Failures list of failures that may occur when attempting to run the exec hook + items: + description: Failure - most of this data is used for posting events and notifications + properties: + error: + description: Error if a golang error was produced during the process of running an exec hook + type: string + exitCode: + description: ExitCode if the script was executed but returned a non-zero exit code it is captured here. Note that customers can define their own exit code with special meanings to them + type: integer + isExecError: + description: IsExecError this indicates that the script itself returned an error vs an error in other parts of the process such as copying the script onto the container + type: boolean + isTimeout: + description: IsTimeout indicates that the exec hook took too long and was abandoned, this is parity with Astra + type: boolean + stderr: + description: Stderr the stderr captured when executing the script + type: string + timeoutMinutes: + description: TimeoutMinutes indicates the amount of time that was given to the exec hook to run. In astra it is used for Activity/Event/Notification messages + type: integer + required: + - isExecError + - isTimeout + type: object + type: array + jobName: + description: JobName name of the job created to run an execution hook + type: string + namespace: + description: Namespace the namespace from the target application where the container is located + type: string + podName: + description: PodName the name of the pod where the exec hook will be run + type: string + podUID: + description: PodUID the uid of the pod where the exec hook will be run + type: string + startTimestamp: + description: StartedTimestamp the time the exec hook started running + format: date-time + type: string + required: + - containerImage + - containerName + - execHookRef + - execHookUID + - namespace + - podName + - podUID + type: object + type: array + state: + description: State indicates a high level summary of the ExecHooksRun's state + type: string + required: + - state + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: kopiavolumebackups.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: KopiaVolumeBackup + listKind: KopiaVolumeBackupList + plural: kopiavolumebackups + singular: kopiavolumebackup + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: KopiaVolumeBackup is the Schema for the kopiavolumebackups API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: KopiaVolumeBackupSpec defines the desired state of KopiaVolumeBackup + properties: + foo: + description: Foo is an example field of KopiaVolumeBackup. Edit kopiavolumebackup_types.go to remove/update + type: string + type: object + status: + description: KopiaVolumeBackupStatus defines the observed state of KopiaVolumeBackup + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: kopiavolumerestores.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: KopiaVolumeRestore + listKind: KopiaVolumeRestoreList + plural: kopiavolumerestores + singular: kopiavolumerestore + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: KopiaVolumeRestore is the Schema for the kopiavolumerestores API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: KopiaVolumeRestoreSpec defines the desired state of KopiaVolumeRestore + properties: + foo: + description: Foo is an example field of KopiaVolumeRestore. Edit kopiavolumerestore_types.go to remove/update + type: string + type: object + status: + description: KopiaVolumeRestoreStatus defines the observed state of KopiaVolumeRestore + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: pvccopies.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: PvcCopy + listKind: PvcCopyList + plural: pvccopies + singular: pvccopy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: PvcCopy is the Schema for the pvccopies API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: PvcCopySpec defines the desired state of PvcCopy + properties: + namespace: + description: cluster namespace in which the source and target PVCs belong to + type: string + sourcePVCRef: + description: SourcePVCRef name of the source PVC where the data is copied from + type: string + targetPVCRef: + description: TargetPVCRef name of the target PVC where the data is copied into + type: string + required: + - namespace + - sourcePVCRef + - targetPVCRef + type: object + status: + description: PvcCopyStatus defines the observed state of PvcCopy + properties: + completionTimestamp: + description: CompletionTimestamp is the server time when the PvcErase is completed. + format: date-time + nullable: true + type: string + conditions: + description: Condition contains details for one aspect of the current state of this PvcErase job + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: pvcerases.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: PvcErase + listKind: PvcEraseList + plural: pvcerases + singular: pvcerase + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: PvcErase is the Schema for the pvcerases API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: PvcEraseSpec defines the desired state of PvcErase + properties: + pvcRef: + description: PVCRef Config for the PVC to erase + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + required: + - pvcRef + type: object + status: + description: PvcEraseStatus defines the observed state of PvcErase + properties: + completionTimestamp: + description: CompletionTimestamp is the server time when the PvcErase is completed. + format: date-time + nullable: true + type: string + conditions: + description: Condition contains details for one aspect of the current state of this PvcErase job + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: resourcebackups.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: ResourceBackup + listKind: ResourceBackupList + plural: resourcebackups + singular: resourcebackup + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ResourceBackup is the Schema for the resourcebackups API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ResourceBackupSpec defines the desired state of ResourceBackup + properties: + appArchivePath: + description: AppArchivePath is the path inside AppVault where the contents of this resourcebackup will go. + type: string + appVaultRef: + description: AppVaultRef is the reference to the AppVault where the snapshot contents will go. + type: string + applicationRef: + description: ApplicationRef is the unique name of the application this resourcebackup is for. + type: string + reclaimPolicy: + description: ReclaimPolicy defines what happens to the resource contents in the app vault when the ResourceBackup CR is deleted Valid options are Retain, Delete (default). + type: string + type: object + status: + description: ResourceBackupStatus defines the observed state of ResourceBackup + properties: + appArchivePath: + description: AppArchivePath is the path where the resourcebackup was archived in the AppVault. + type: string + completionTimestamp: + description: CompletionTimestamp is the server time when the resourcebackup was completed. + format: date-time + nullable: true + type: string + conditions: + description: Each Condition contains details for one aspect of the current state of the ResourceBackup. + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + error: + description: Error indicates the most recent error that has occurred. The error may not be permanent, so progress may continue after temporarily seeing an error. + type: string + state: + description: State indicates a high level summary of the ResourceBackup's state + type: string + required: + - conditions + - state + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: resourcedeletes.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: ResourceDelete + listKind: ResourceDeleteList + plural: resourcedeletes + singular: resourcedelete + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ResourceDelete is the Schema for the resourcedeletes API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ResourceDeleteSpec defines the desired state of ResourceDelete + properties: + appArchivePath: + description: AppArchivePath is the path inside AppVault where the contents of this collection will be read from. + type: string + appVaultRef: + description: AppVaultRef is the reference to the AppVault where the snapshot contents will be read from. + type: string + exclusionResourceList: + description: ExclusionResourceList is an optional list of objects to exclude from being deleted. + items: + description: GroupKind defines a kubernetes object + properties: + group: + description: Group is the server time when the ResourceDelete is completed. + type: string + kind: + description: Kind + type: string + required: + - group + - kind + type: object + type: array + resourceFilter: + description: ResourceFilter should be populated by the user if only certain resources must be restored in the target namespace + properties: + resourceMatchers: + description: ResourceMatchers is a list of matchers where each matcher matches one or more resources + items: + properties: + group: + description: Group of the kubernetes resource that has to be matched + type: string + kind: + description: Kind of the kubernetes resource that has to be matched + type: string + labelSelectors: + description: LabelSelectors is used to match resource(s) based on the metadata.labels field of the kubernetes resource + items: + type: string + type: array + names: + description: Names kubernetes metadata.name field of the resource(s) that must be matched. + items: + type: string + type: array + namespaces: + description: Namespaces kubernetes metadata.namespace field of the resource(s) that must be matched. + items: + type: string + type: array + version: + description: Version of the kubernetes resource that has to be matched. + type: string + type: object + type: array + resourceSelectionCriteria: + description: ResourceSelectionCriteria used to determine if the resources matching the provided resources matchers should be included into the collection or excluded from the collection. + enum: + - include + - exclude + type: string + type: object + type: object + status: + description: ResourceDeleteStatus defines the observed state of ResourceDelete + properties: + completionTimestamp: + description: CompletionTimestamp is the server time when the ResourceDelete is completed. + format: date-time + nullable: true + type: string + conditions: + description: Condition contains details for one aspect of the current state of this ResourceDelete resource + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: resourcerestores.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: ResourceRestore + listKind: ResourceRestoreList + plural: resourcerestores + singular: resourcerestore + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ResourceRestore is the Schema for the resourcerestores API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ResourceRestoreSpec defines the desired state of ResourceRestore + properties: + appArchivePath: + description: AppArchivePath is the path inside AppVault where the contents of this collection will be read from. + type: string + appVaultRef: + description: AppVaultRef is the reference to the AppVault where the snapshot contents will be read from. + type: string + namespaceMapping: + description: NamespaceMapping is the mapping between source namespace to target namespace + items: + properties: + destination: + description: Destination namespace where the single resource will be cloned into + type: string + source: + description: Source namespace of a single resource in the collection + type: string + required: + - destination + - source + type: object + type: array + resourceFilter: + description: ResourceFilter should be populated by the user if only certain resources must be restored in the target namespace + properties: + resourceMatchers: + description: ResourceMatchers is a list of matchers where each matcher matches one or more resources + items: + properties: + group: + description: Group of the kubernetes resource that has to be matched + type: string + kind: + description: Kind of the kubernetes resource that has to be matched + type: string + labelSelectors: + description: LabelSelectors is used to match resource(s) based on the metadata.labels field of the kubernetes resource + items: + type: string + type: array + names: + description: Names kubernetes metadata.name field of the resource(s) that must be matched. + items: + type: string + type: array + namespaces: + description: Namespaces kubernetes metadata.namespace field of the resource(s) that must be matched. + items: + type: string + type: array + version: + description: Version of the kubernetes resource that has to be matched. + type: string + type: object + type: array + resourceSelectionCriteria: + description: ResourceSelectionCriteria used to determine if the resources matching the provided resources matchers should be included into the collection or excluded from the collection. + enum: + - include + - exclude + type: string + type: object + type: object + status: + description: ResourceRestoreStatus defines the observed state of ResourceRestore + properties: + completionTimestamp: + description: CompletionTimestamp is the server time when the ResourceRestore is completed. + format: date-time + nullable: true + type: string + conditions: + description: Condition contains details for one aspect of the current state of this ResourceRestore resource + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: resourcesummaryuploads.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: ResourceSummaryUpload + listKind: ResourceSummaryUploadList + plural: resourcesummaryuploads + singular: resourcesummaryupload + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ResourceSummaryUpload is the Schema for the resourcesummaryuploads API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ResourceSummaryUploadSpec defines the desired state of ResourceSummaryUpload + properties: + dataSourceRef: + description: TypedLocalObjectReference contains enough information to let you locate the typed referenced object inside the same namespace. + properties: + apiGroup: + description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + hostNameAlias: + type: string + pushEndpoint: + type: string + pushToken: + properties: + valueFromSecret: + description: ValueFromSecret indicates that the credential value should come from a secret. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: Name of the secret containing the value for this field. Must be in the same namespace. + type: string + required: + - key + - name + type: object + required: + - valueFromSecret + type: object + skipCertValidation: + type: boolean + required: + - dataSourceRef + - pushEndpoint + - pushToken + type: object + status: + description: ResourceSummaryUploadStatus defines the observed state of ResourceSummaryUpload + properties: + completionTimestamp: + description: CompletionTimestamp is the server time when the resourcesummaryupload was completed. + format: date-time + nullable: true + type: string + conditions: + description: Each Condition contains details for one aspect of the current state of the ResourceSummaryUpload. + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + error: + type: string + state: + type: string + required: + - conditions + - state + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: resticvolumebackups.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: ResticVolumeBackup + listKind: ResticVolumeBackupList + plural: resticvolumebackups + singular: resticvolumebackup + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.state + name: State + type: string + - jsonPath: .status.error + name: Error + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ResticVolumeBackup is the Schema for the resticvolumebackups API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ResticVolumeBackupSpec defines the desired state of ResticVolumeBackup + properties: + clonePVC: + description: Config for the temporary clone PVC that will be created to access the snapshot contents (if dataSource is a VolumeSnapshot) + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: ResourceList is a set of (resource name, quantity) pairs. + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: ResourceList is a set of (resource name, quantity) pairs. + type: object + type: object + storageClassName: + type: string + type: object + type: object + dataSourceRef: + description: Reference to the PVC or VolumeSnapshot to use as the source of the backup + properties: + apiGroup: + description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + reclaimPolicy: + description: ReclaimPolicy defines what happens to the ResticSnapshot of a restic backup when the ResticVolumeBackup CR is deleted Valid options are Retain, Delete (default). + type: string + resticEnv: + description: Env vars to be provided to the restic CLI (including any required credentials) + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + resticRepository: + description: Restic repository location (specified in the same format as the "-r" option of the restic CLI) + type: string + resticVolumeMounts: + description: ResticVolumeMounts contains information about the restic secrets to be mounted on the restic pod + items: + properties: + mount: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + source: + description: "Adapts a Secret into a volume. \n The contents of the target Secret's Data field will be presented in a volume as files using the keys in the Data field as the file names. Secret volumes support ownership management and SELinux relabeling." + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + type: object + type: array + required: + - dataSourceRef + - resticEnv + - resticRepository + type: object + status: + description: ResticVolumeBackupStatus defines the observed state of ResticVolumeBackup + properties: + clonePVCName: + description: Name of the temporary clone PVC created for Restic to copy from (if dataSourceRef is a VolumeSnapshot) + type: string + clonePVName: + description: Name of the temporary clone PV created for the PVC. + type: string + completionTimestamp: + description: CompletionTimestamp records the time the ResticVolumeBackup completed. The server's time is used for CompletionTimestamps + format: date-time + nullable: true + type: string + conditions: + description: Each Condition contains details for one aspect of the current state of the ResticVolumeBackup. + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + error: + description: Error indicates the most recent error that has occurred. The error may not be permanent, so progress may continue after temporarily seeing an error. + type: string + resticDeleteJobName: + description: Name of the Job created to run Restic delete + type: string + resticJobName: + description: Name of the Job created to run Restic + type: string + resticSnapshotID: + description: ID of the Restic snapshot created to represent this backup + type: string + state: + description: State indicates a high level summary of the ResticVolumeBackup's state + type: string + required: + - clonePVName + - conditions + - state + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: resticvolumerestores.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: ResticVolumeRestore + listKind: ResticVolumeRestoreList + plural: resticvolumerestores + singular: resticvolumerestore + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ResticVolumeRestore is the Schema for the resticvolumerestores API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ResticVolumeRestoreSpec defines the desired state of ResticVolumeRestore + properties: + resticEnv: + description: Env vars to be provided to the restic CLI (including any required credentials) + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + resticRepository: + description: Restic repository location (specified in the same format as the "-r" option of the restic CLI) + type: string + resticSnapshotID: + description: ID of the Restic snapshot that needs to be restored + type: string + resticVolumeMounts: + description: ResticVolumeMounts contains information about the restic secrets to be mounted on the restic pod + items: + properties: + mount: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + source: + description: "Adapts a Secret into a volume. \n The contents of the target Secret's Data field will be presented in a volume as files using the keys in the Data field as the file names. Secret volumes support ownership management and SELinux relabeling." + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + type: object + type: array + targetPVCRef: + description: Config for the PVC to restore the restic snapshot into + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + required: + - resticEnv + - resticRepository + - resticSnapshotID + - targetPVCRef + type: object + status: + description: ResticVolumeRestoreStatus defines the observed state of ResticVolumeRestore + properties: + resticJobCleanedUp: + description: Indicates whether the Restic job has been cleaned up + type: boolean + resticJobInfo: + description: Information about the restic job + properties: + bytesComplete: + description: bytes of data copied into the volume so far + format: int64 + type: integer + name: + type: string + namespace: + type: string + status: + description: status of the current restic restore + type: string + required: + - bytesComplete + - name + - namespace + - status + type: object + required: + - resticJobCleanedUp + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: schedules.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: Schedule + listKind: ScheduleList + plural: schedules + singular: schedule + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: Schedule is the Schema for the schedules API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ScheduleSpec defines the desired state of Schedule + properties: + appVaultRef: + description: Name of the AppVault to use as the target of the backup/snapshot + type: string + applicationRef: + description: ApplicationRef is the reference to the Application. + type: string + backupRetention: + description: Indicates how many backups to retain. Zero indicates that no backups should be created. + maxLength: 63 + minLength: 0 + pattern: ^(0|([1-9][0-9]*))$ + type: string + dayOfMonth: + description: Numeric value indicating the day of the month (1-31) to execute the schedule. This field is only present if granularity is set to "monthly". + type: string + dayOfWeek: + description: Numeric value indicating the day of the week (0-7) to execute the schedule. This field is only present if granularity is set to "weekly". + type: string + enabled: + default: true + description: Indicates if a schedule is active. + type: boolean + granularity: + description: Indicates the granularity of the schedule. + enum: + - hourly + - daily + - weekly + - monthly + - custom + type: string + hour: + description: Numeric value indicating the hour of the day (0 - 23) to execute the schedule. This field is present if granularity is set to "daily", "weekly", or "monthly". + type: string + minute: + description: Numeric value indicating the minute of the hour (0 - 59) to execute the schedule. This field is present if granularity is set to "hourly", "daily", "weekly", or "monthly". + type: string + recurrenceRule: + description: string containing an RFC-5545 Section 3.8.5.3. Recurrence Rule. For the DTSTART parameter, only UTC timestamps (denoted by the "Z" suffix) are supported, and only timestamps before the current time are supported. For the RECUR rule parts, "FREQ" and "INTERVAL" are the only rule parts supported. For the FREQ rule part, "MINUTELY" and "HOURLY" are the only values supported. This field is only present if granularity is set to "custom". + type: string + snapshotRetention: + description: Indicates how many snapshots to retain. Zero indicates that no snapshots should be created. + maxLength: 63 + minLength: 0 + pattern: ^(0|([1-9][0-9]*))$ + type: string + required: + - appVaultRef + - backupRetention + - granularity + - snapshotRetention + type: object + status: + description: ScheduleStatus defines the observed state of Schedule + properties: + lastScheduleTime: + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: shutdownsnapshots.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: ShutdownSnapshot + listKind: ShutdownSnapshotList + plural: shutdownsnapshots + singular: shutdownsnapshot + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.state + name: State + type: string + - jsonPath: .status.error + name: Error + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ShutdownSnapshot is the Schema for the shutdownsnapshots API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: SnapshotSpec defines the desired state of Snapshot + properties: + appVaultRef: + description: AppVaultRef is the reference to the AppVault where the snapshot contents will go. + type: string + applicationRef: + description: ApplicationRef is the reference to the Application being snapshotted. + type: string + completionTimeout: + description: CompletionTimeout specifies the time to wait for the entire Snapshot to complete before returning timeout error. The default value is 60 minutes. + type: string + reclaimPolicy: + description: ReclaimPolicy defines what happens to the AppArchive of a snapshot when the snapshot CR is deleted Valid options are Retain, Delete (default). + type: string + volumeSnapshotsCreatedTimeout: + description: VolumeSnapshotsCreatedTimeout specifies the time to wait for all VolumeSnapshots CreationTime to be set before returning timeout error. The default value is 5 minutes. + type: string + volumeSnapshotsReadyToUseTimeout: + description: VolumeSnapshotsReadyToUseTimeout specifies the time to wait for Snapshot CR to complete before returning timeout error. The default value is 30 minutes. + type: string + type: object + status: + description: SnapshotStatus defines the observed state of Snapshot + properties: + appArchivePath: + description: AppArchivePath is the path where the snapshot was archived in the AppVault. + type: string + completionTimestamp: + description: CompletionTimestamp is the server time when the snapshot was completed. + format: date-time + nullable: true + type: string + conditions: + description: Each Condition contains details for one aspect of the current state of the Snapshot. + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + error: + description: Error indicates the most recent error that has occurred. The error may not be permanent, so progress may continue after temporarily seeing an error. + type: string + postSnapshotExecHooksRunResults: + description: PostSnapshotExecHooksRunResults contains the results of executing hooks during the post/snapshot stage/action + items: + properties: + completionTimestamp: + description: CompletionTimestamp the time the exec hook run was finished regardless of failures + format: date-time + type: string + containerImage: + description: ContainerImage the image of the container the exec hook is run on + type: string + containerName: + description: ContainerName the name of the container the exec hook is run on + type: string + execHookRef: + description: ExecHookRef reference to the ExecHook being run + type: string + execHookUID: + description: ExecHookUID UID of the ExecHook being run + type: string + failures: + description: Failures list of failures that may occur when attempting to run the exec hook + items: + description: Failure - most of this data is used for posting events and notifications + properties: + error: + description: Error if a golang error was produced during the process of running an exec hook + type: string + exitCode: + description: ExitCode if the script was executed but returned a non-zero exit code it is captured here. Note that customers can define their own exit code with special meanings to them + type: integer + isExecError: + description: IsExecError this indicates that the script itself returned an error vs an error in other parts of the process such as copying the script onto the container + type: boolean + isTimeout: + description: IsTimeout indicates that the exec hook took too long and was abandoned, this is parity with Astra + type: boolean + stderr: + description: Stderr the stderr captured when executing the script + type: string + timeoutMinutes: + description: TimeoutMinutes indicates the amount of time that was given to the exec hook to run. In astra it is used for Activity/Event/Notification messages + type: integer + required: + - isExecError + - isTimeout + type: object + type: array + jobName: + description: JobName name of the job created to run an execution hook + type: string + namespace: + description: Namespace the namespace from the target application where the container is located + type: string + podName: + description: PodName the name of the pod where the exec hook will be run + type: string + podUID: + description: PodUID the uid of the pod where the exec hook will be run + type: string + startTimestamp: + description: StartedTimestamp the time the exec hook started running + format: date-time + type: string + required: + - containerImage + - containerName + - execHookRef + - execHookUID + - namespace + - podName + - podUID + type: object + type: array + preSnapshotExecHooksRunResults: + description: PreSnapshotExecHooksRunResults contains the results of executing hooks during the pre/snapshot stage/action + items: + properties: + completionTimestamp: + description: CompletionTimestamp the time the exec hook run was finished regardless of failures + format: date-time + type: string + containerImage: + description: ContainerImage the image of the container the exec hook is run on + type: string + containerName: + description: ContainerName the name of the container the exec hook is run on + type: string + execHookRef: + description: ExecHookRef reference to the ExecHook being run + type: string + execHookUID: + description: ExecHookUID UID of the ExecHook being run + type: string + failures: + description: Failures list of failures that may occur when attempting to run the exec hook + items: + description: Failure - most of this data is used for posting events and notifications + properties: + error: + description: Error if a golang error was produced during the process of running an exec hook + type: string + exitCode: + description: ExitCode if the script was executed but returned a non-zero exit code it is captured here. Note that customers can define their own exit code with special meanings to them + type: integer + isExecError: + description: IsExecError this indicates that the script itself returned an error vs an error in other parts of the process such as copying the script onto the container + type: boolean + isTimeout: + description: IsTimeout indicates that the exec hook took too long and was abandoned, this is parity with Astra + type: boolean + stderr: + description: Stderr the stderr captured when executing the script + type: string + timeoutMinutes: + description: TimeoutMinutes indicates the amount of time that was given to the exec hook to run. In astra it is used for Activity/Event/Notification messages + type: integer + required: + - isExecError + - isTimeout + type: object + type: array + jobName: + description: JobName name of the job created to run an execution hook + type: string + namespace: + description: Namespace the namespace from the target application where the container is located + type: string + podName: + description: PodName the name of the pod where the exec hook will be run + type: string + podUID: + description: PodUID the uid of the pod where the exec hook will be run + type: string + startTimestamp: + description: StartedTimestamp the time the exec hook started running + format: date-time + type: string + required: + - containerImage + - containerName + - execHookRef + - execHookUID + - namespace + - podName + - podUID + type: object + type: array + state: + description: State indicates a high level summary of the Snapshot's state + type: string + volumeSnapshots: + description: Used to internally track volume snapshot progress + items: + description: NamespacedName creating this, since the k8s.io/apimachinery/pkg/types.NamespacedName does not have json tags associated with it. + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + type: array + required: + - state + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: snapshotinplacerestores.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: SnapshotInplaceRestore + listKind: SnapshotInplaceRestoreList + plural: snapshotinplacerestores + singular: snapshotinplacerestore + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.state + name: State + type: string + - jsonPath: .status.error + name: Error + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: SnapshotInplaceRestore is the Schema for the snapshotinplacerestores API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: SnapshotInplaceRestoreSpec defines the desired state of SnapshotInplaceRestore + properties: + appArchivePath: + description: AppArchivePath is the path inside AppVault where the snapshot contents are stored. + type: string + appVaultRef: + description: AppVaultRef is the reference to the AppVault where the snapshot contents are stored. + type: string + namespaceMapping: + description: NamespaceMapping is the mapping between source namespace to target namespace + items: + properties: + destination: + description: Destination namespace where the single resource will be cloned into + type: string + source: + description: Source namespace of a single resource in the collection + type: string + required: + - destination + - source + type: object + type: array + resourceFilter: + description: ResourceFilter should be populated by the user if only certain resources must be restored in the target namespace + properties: + resourceMatchers: + description: ResourceMatchers is a list of matchers where each matcher matches one or more resources + items: + properties: + group: + description: Group of the kubernetes resource that has to be matched + type: string + kind: + description: Kind of the kubernetes resource that has to be matched + type: string + labelSelectors: + description: LabelSelectors is used to match resource(s) based on the metadata.labels field of the kubernetes resource + items: + type: string + type: array + names: + description: Names kubernetes metadata.name field of the resource(s) that must be matched. + items: + type: string + type: array + namespaces: + description: Namespaces kubernetes metadata.namespace field of the resource(s) that must be matched. + items: + type: string + type: array + version: + description: Version of the kubernetes resource that has to be matched. + type: string + type: object + type: array + resourceSelectionCriteria: + description: ResourceSelectionCriteria used to determine if the resources matching the provided resources matchers should be included into the collection or excluded from the collection. + enum: + - include + - exclude + type: string + type: object + type: object + status: + description: SnapshotInplaceRestoreStatus defines the observed state of SnapshotInplaceRestore + properties: + completionTimestamp: + description: CompletionTimestamp records the time the Restore completed. The server's time is used for CompletionTimestamps + format: date-time + nullable: true + type: string + conditions: + description: Each Condition contains details for one aspect of the current state of the SnapshotInplace Restore. + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + error: + description: Error indicates the most recent error that has occurred. The error may not be permanent, so progress may continue after temporarily seeing an error. + type: string + state: + description: 'INSERT ADDITIONAL STATUS FIELD - define observed state of cluster Important: Run "make" to regenerate code after modifying this file State indicates a high level summary of the SnapshotInplace Restore''s state' + type: string + required: + - conditions + - state + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: snapshotrestores.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: SnapshotRestore + listKind: SnapshotRestoreList + plural: snapshotrestores + singular: snapshotrestore + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.state + name: State + type: string + - jsonPath: .status.error + name: Error + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: SnapshotRestore is the Schema for the snapshotrestores API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: SnapshotRestoreSpec defines the desired state of SnapshotRestore + properties: + appArchivePath: + description: AppArchivePath is the path inside AppVault where the snapshot contents are stored. + type: string + appVaultRef: + description: AppVaultRef is the reference to the AppVault where the snapshot contents are stored. + type: string + namespaceMapping: + description: NamespaceMapping is the mapping between source namespace to target namespace + items: + properties: + destination: + description: Destination namespace where the single resource will be cloned into + type: string + source: + description: Source namespace of a single resource in the collection + type: string + required: + - destination + - source + type: object + type: array + resourceFilter: + description: ResourceFilter should be populated by the user if only certain resources must be restored in the target namespace + properties: + resourceMatchers: + description: ResourceMatchers is a list of matchers where each matcher matches one or more resources + items: + properties: + group: + description: Group of the kubernetes resource that has to be matched + type: string + kind: + description: Kind of the kubernetes resource that has to be matched + type: string + labelSelectors: + description: LabelSelectors is used to match resource(s) based on the metadata.labels field of the kubernetes resource + items: + type: string + type: array + names: + description: Names kubernetes metadata.name field of the resource(s) that must be matched. + items: + type: string + type: array + namespaces: + description: Namespaces kubernetes metadata.namespace field of the resource(s) that must be matched. + items: + type: string + type: array + version: + description: Version of the kubernetes resource that has to be matched. + type: string + type: object + type: array + resourceSelectionCriteria: + description: ResourceSelectionCriteria used to determine if the resources matching the provided resources matchers should be included into the collection or excluded from the collection. + enum: + - include + - exclude + type: string + type: object + storageClassMapping: + description: StorageClassMapping defines a mapping from a storageClass present in the source application to the assignment in the restored application (clone) + items: + properties: + destination: + description: Destination storageClass that is assigned to the same PVC in the cloned/restored application + type: string + source: + description: Source storageClass that is assigned to one of the PVCs in the source application + type: string + required: + - destination + - source + type: object + type: array + type: object + status: + description: SnapshotRestoreStatus defines the observed state of SnapshotRestore + properties: + completionTimestamp: + description: CompletionTimestamp records the time the Restore completed. The server's time is used for CompletionTimestamps + format: date-time + nullable: true + type: string + conditions: + description: Condition contains details for one aspect of the current state of this PvcErase job + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + error: + description: Error indicates the most recent error that has occurred. The error may not be permanent, so progress may continue after temporarily seeing an error. + type: string + state: + description: State indicates a high level summary of the SnapshotRestore operations state + type: string + warnings: + description: Warnings contains warnings that have occurred during execution + items: + type: string + type: array + required: + - state + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: snapshots.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: Snapshot + listKind: SnapshotList + plural: snapshots + singular: snapshot + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.state + name: State + type: string + - jsonPath: .status.error + name: Error + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: Snapshot is the Schema for the snapshots API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: SnapshotSpec defines the desired state of Snapshot + properties: + appVaultRef: + description: AppVaultRef is the reference to the AppVault where the snapshot contents will go. + type: string + applicationRef: + description: ApplicationRef is the reference to the Application being snapshotted. + type: string + completionTimeout: + description: CompletionTimeout specifies the time to wait for the entire Snapshot to complete before returning timeout error. The default value is 60 minutes. + type: string + reclaimPolicy: + description: ReclaimPolicy defines what happens to the AppArchive of a snapshot when the snapshot CR is deleted Valid options are Retain, Delete (default). + type: string + volumeSnapshotsCreatedTimeout: + description: VolumeSnapshotsCreatedTimeout specifies the time to wait for all VolumeSnapshots CreationTime to be set before returning timeout error. The default value is 5 minutes. + type: string + volumeSnapshotsReadyToUseTimeout: + description: VolumeSnapshotsReadyToUseTimeout specifies the time to wait for Snapshot CR to complete before returning timeout error. The default value is 30 minutes. + type: string + type: object + status: + description: SnapshotStatus defines the observed state of Snapshot + properties: + appArchivePath: + description: AppArchivePath is the path where the snapshot was archived in the AppVault. + type: string + completionTimestamp: + description: CompletionTimestamp is the server time when the snapshot was completed. + format: date-time + nullable: true + type: string + conditions: + description: Each Condition contains details for one aspect of the current state of the Snapshot. + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + error: + description: Error indicates the most recent error that has occurred. The error may not be permanent, so progress may continue after temporarily seeing an error. + type: string + postSnapshotExecHooksRunResults: + description: PostSnapshotExecHooksRunResults contains the results of executing hooks during the post/snapshot stage/action + items: + properties: + completionTimestamp: + description: CompletionTimestamp the time the exec hook run was finished regardless of failures + format: date-time + type: string + containerImage: + description: ContainerImage the image of the container the exec hook is run on + type: string + containerName: + description: ContainerName the name of the container the exec hook is run on + type: string + execHookRef: + description: ExecHookRef reference to the ExecHook being run + type: string + execHookUID: + description: ExecHookUID UID of the ExecHook being run + type: string + failures: + description: Failures list of failures that may occur when attempting to run the exec hook + items: + description: Failure - most of this data is used for posting events and notifications + properties: + error: + description: Error if a golang error was produced during the process of running an exec hook + type: string + exitCode: + description: ExitCode if the script was executed but returned a non-zero exit code it is captured here. Note that customers can define their own exit code with special meanings to them + type: integer + isExecError: + description: IsExecError this indicates that the script itself returned an error vs an error in other parts of the process such as copying the script onto the container + type: boolean + isTimeout: + description: IsTimeout indicates that the exec hook took too long and was abandoned, this is parity with Astra + type: boolean + stderr: + description: Stderr the stderr captured when executing the script + type: string + timeoutMinutes: + description: TimeoutMinutes indicates the amount of time that was given to the exec hook to run. In astra it is used for Activity/Event/Notification messages + type: integer + required: + - isExecError + - isTimeout + type: object + type: array + jobName: + description: JobName name of the job created to run an execution hook + type: string + namespace: + description: Namespace the namespace from the target application where the container is located + type: string + podName: + description: PodName the name of the pod where the exec hook will be run + type: string + podUID: + description: PodUID the uid of the pod where the exec hook will be run + type: string + startTimestamp: + description: StartedTimestamp the time the exec hook started running + format: date-time + type: string + required: + - containerImage + - containerName + - execHookRef + - execHookUID + - namespace + - podName + - podUID + type: object + type: array + preSnapshotExecHooksRunResults: + description: PreSnapshotExecHooksRunResults contains the results of executing hooks during the pre/snapshot stage/action + items: + properties: + completionTimestamp: + description: CompletionTimestamp the time the exec hook run was finished regardless of failures + format: date-time + type: string + containerImage: + description: ContainerImage the image of the container the exec hook is run on + type: string + containerName: + description: ContainerName the name of the container the exec hook is run on + type: string + execHookRef: + description: ExecHookRef reference to the ExecHook being run + type: string + execHookUID: + description: ExecHookUID UID of the ExecHook being run + type: string + failures: + description: Failures list of failures that may occur when attempting to run the exec hook + items: + description: Failure - most of this data is used for posting events and notifications + properties: + error: + description: Error if a golang error was produced during the process of running an exec hook + type: string + exitCode: + description: ExitCode if the script was executed but returned a non-zero exit code it is captured here. Note that customers can define their own exit code with special meanings to them + type: integer + isExecError: + description: IsExecError this indicates that the script itself returned an error vs an error in other parts of the process such as copying the script onto the container + type: boolean + isTimeout: + description: IsTimeout indicates that the exec hook took too long and was abandoned, this is parity with Astra + type: boolean + stderr: + description: Stderr the stderr captured when executing the script + type: string + timeoutMinutes: + description: TimeoutMinutes indicates the amount of time that was given to the exec hook to run. In astra it is used for Activity/Event/Notification messages + type: integer + required: + - isExecError + - isTimeout + type: object + type: array + jobName: + description: JobName name of the job created to run an execution hook + type: string + namespace: + description: Namespace the namespace from the target application where the container is located + type: string + podName: + description: PodName the name of the pod where the exec hook will be run + type: string + podUID: + description: PodUID the uid of the pod where the exec hook will be run + type: string + startTimestamp: + description: StartedTimestamp the time the exec hook started running + format: date-time + type: string + required: + - containerImage + - containerName + - execHookRef + - execHookUID + - namespace + - podName + - podUID + type: object + type: array + state: + description: State indicates a high level summary of the Snapshot's state + type: string + volumeSnapshots: + description: Used to internally track volume snapshot progress + items: + description: NamespacedName creating this, since the k8s.io/apimachinery/pkg/types.NamespacedName does not have json tags associated with it. + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + type: array + required: + - state + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: neptune + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: serviceaccount + app.kubernetes.io/part-of: neptune + name: neptune-autosupportbundle + namespace: astra-connector +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: neptune + app.kubernetes.io/instance: controller-manager + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: serviceaccount + app.kubernetes.io/part-of: neptune + name: neptune-controller-manager + namespace: astra-connector +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: neptune + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: serviceaccount + app.kubernetes.io/part-of: neptune + name: neptune-exechook + namespace: astra-connector +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: neptune + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: serviceaccount + app.kubernetes.io/part-of: neptune + name: neptune-resourcebackup + namespace: astra-connector +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: neptune + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: serviceaccount + app.kubernetes.io/part-of: neptune + name: neptune-resourcedelete + namespace: astra-connector +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: neptune + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: serviceaccount + app.kubernetes.io/part-of: neptune + name: neptune-resourcerestore + namespace: astra-connector +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: neptune + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: serviceaccount + app.kubernetes.io/part-of: neptune + name: neptune-resourcesummaryupload + namespace: astra-connector +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: neptune + app.kubernetes.io/instance: leader-election-role + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: role + app.kubernetes.io/part-of: neptune + name: neptune-leader-election-role + namespace: astra-connector +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + creationTimestamp: null + name: neptune-manager-role + namespace: astra-connector +rules: +- apiGroups: + - '*' + resources: + - secrets + verbs: + - get + - list +- apiGroups: + - astra.netapp.io + resources: + - applications + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - applications/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - applications/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - appmirrorrelationships + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - appmirrorrelationships/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - appmirrorrelationships/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - appmirrorupdates + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - appmirrorupdates/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - appmirrorupdates/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - appvaults + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - appvaults/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - appvaults/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - autosupportbundles + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - autosupportbundles/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - autosupportbundles/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - backupinplacerestores + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - backupinplacerestores/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - backupinplacerestores/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - backuprestores + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - backuprestores/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - backuprestores/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - backups + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - backups/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - backups/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - pvccopies + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - pvccopies/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - pvccopies/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - pvcerases + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - pvcerases/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - pvcerases/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - resourcebackups + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - resourcebackups/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - resourcebackups/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - resourcedeletes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - resourcedeletes/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - resourcedeletes/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - resourcerestores + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - resourcerestores/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - resourcerestores/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - resourcesummaryuploads + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - resourcesummaryuploads/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - resourcesummaryuploads/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - resticvolumebackups + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - resticvolumebackups/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - resticvolumebackups/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - resticvolumerestores + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - resticvolumerestores/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - resticvolumerestores/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - schedules + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - schedules/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - schedules/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - shutdownsnapshots + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - shutdownsnapshots/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - shutdownsnapshots/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - snapshotinplacerestores + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - snapshotinplacerestores/finalizers + verbs: + - create + - get + - list + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - snapshotinplacerestores/status + verbs: + - get + - list + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - snapshotrestores + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - snapshotrestores/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - snapshotrestores/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - snapshots + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - snapshots/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - snapshots/status + verbs: + - get + - patch + - update +- apiGroups: + - batch + resources: + - jobs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - batch + resources: + - jobs/finalizers + verbs: + - create + - delete + - update +- apiGroups: + - batch + resources: + - jobs/status + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: neptune-autosupportbundle +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - get + - list +- apiGroups: + - '*' + resourceNames: + - kube-system + resources: + - namespaces + verbs: + - get +- apiGroups: + - '*' + resources: + - pods + verbs: + - list +- apiGroups: + - '*' + resources: + - pods/log + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: neptune-exechook +rules: +- apiGroups: + - "" + resources: + - pods/exec + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: neptune-manager-role +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - namespaces + verbs: + - create + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - persistentvolumeclaims + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - persistentvolumes + verbs: + - create + - get + - list + - update + - watch +- apiGroups: + - "" + resources: + - pods + verbs: + - delete + - get + - list + - update + - watch +- apiGroups: + - "" + resources: + - pods/finalizers + verbs: + - delete + - update +- apiGroups: + - "" + resources: + - pods/log + verbs: + - get + - list +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - get + - list + - watch +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - create + - delete + - get + - list + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - '*' + verbs: + - get + - list + - watch +- apiGroups: + - astra.netapp.io + resources: + - autosupportbundleschedules + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - autosupportbundleschedules/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - autosupportbundleschedules/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - exechooks + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - exechooks/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - exechooks/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - exechooksruns + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - exechooksruns/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - exechooksruns/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - kopiavolumebackups + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - kopiavolumebackups/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - kopiavolumebackups/status + verbs: + - get + - patch + - update +- apiGroups: + - astra.netapp.io + resources: + - kopiavolumerestores + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - kopiavolumerestores/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - kopiavolumerestores/status + verbs: + - get + - patch + - update +- apiGroups: + - batch + resources: + - jobs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - batch + resources: + - jobs/finalizers + verbs: + - create + - delete + - update +- apiGroups: + - batch + resources: + - jobs/status + verbs: + - get +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - get + - list + - patch + - update + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + - roles + verbs: + - create + - delete + - get + - list + - update + - watch +- apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + verbs: + - create + - delete + - get + - list + - use +- apiGroups: + - snapshot.storage.k8s.io + resources: + - volumesnapshotclasses + verbs: + - get + - list + - watch +- apiGroups: + - snapshot.storage.k8s.io + resources: + - volumesnapshotcontents + verbs: + - create + - delete + - get + - list + - patch + - watch +- apiGroups: + - snapshot.storage.k8s.io + resources: + - volumesnapshotcontents/status + verbs: + - get + - patch + - update +- apiGroups: + - snapshot.storage.k8s.io + resources: + - volumesnapshots + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - snapshot.storage.k8s.io + resources: + - volumesnapshots/finalizers + verbs: + - update +- apiGroups: + - snapshot.storage.k8s.io + resources: + - volumesnapshots/status + verbs: + - get + - patch + - update +- apiGroups: + - storage.k8s.io + resources: + - storageclasses + verbs: + - get + - list + - watch +- apiGroups: + - trident.netapp.io + resources: + - tridentactionmirrorupdates + verbs: + - create + - delete + - get + - list + - update + - watch +- apiGroups: + - trident.netapp.io + resources: + - tridentbackends + verbs: + - get + - list + - watch +- apiGroups: + - trident.netapp.io + resources: + - tridentmirrorrelationships + verbs: + - create + - delete + - get + - list + - update + - watch +- apiGroups: + - trident.netapp.io + resources: + - tridentvolumes + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/created-by: neptune + app.kubernetes.io/instance: metrics-reader + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrole + app.kubernetes.io/part-of: neptune + name: neptune-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/created-by: neptune + app.kubernetes.io/instance: proxy-role + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrole + app.kubernetes.io/part-of: neptune + name: neptune-proxy-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: neptune-resourcebackup +rules: +- nonResourceURLs: + - '*' + verbs: + - get + - list +- apiGroups: + - '*' + resources: + - '*' + verbs: + - get + - list + - use +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: neptune-resourcedelete +rules: +- nonResourceURLs: + - '*' + verbs: + - delete +- apiGroups: + - '*' + resources: + - '*' + verbs: + - delete + - use +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: neptune-resourcerestore +rules: +- nonResourceURLs: + - '*' + verbs: + - '*' +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: neptune-resourcesummaryupload +rules: +- nonResourceURLs: + - '*' + verbs: + - get + - list + - use +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: neptune + app.kubernetes.io/instance: leader-election-rolebinding + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: rolebinding + app.kubernetes.io/part-of: neptune + name: neptune-leader-election-rolebinding + namespace: astra-connector +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: neptune-leader-election-role +subjects: +- kind: ServiceAccount + name: neptune-controller-manager + namespace: astra-connector +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: neptune + app.kubernetes.io/instance: manager-rolebinding + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: rolebinding + app.kubernetes.io/part-of: neptune + name: neptune-manager-rolebinding + namespace: astra-connector +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: neptune-manager-role +subjects: +- kind: ServiceAccount + name: neptune-controller-manager + namespace: astra-connector +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: neptune + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: serviceaccount + app.kubernetes.io/part-of: neptune + name: neptune-autosupportbundle +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: neptune-autosupportbundle +subjects: +- kind: ServiceAccount + name: neptune-autosupportbundle + namespace: astra-connector +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: neptune + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: serviceaccount + app.kubernetes.io/part-of: neptune + name: neptune-autosupportbundle-metrics +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: neptune-metrics-reader +subjects: +- kind: ServiceAccount + name: neptune-autosupportbundle + namespace: astra-connector +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: neptune + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: serviceaccount + app.kubernetes.io/part-of: neptune + name: neptune-exechook +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: neptune-exechook +subjects: +- kind: ServiceAccount + name: neptune-exechook + namespace: astra-connector +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: neptune + app.kubernetes.io/instance: manager-rolebinding + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrolebinding + app.kubernetes.io/part-of: neptune + name: neptune-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: neptune-manager-role +subjects: +- kind: ServiceAccount + name: neptune-controller-manager + namespace: astra-connector +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/created-by: neptune + app.kubernetes.io/instance: proxy-rolebinding + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: clusterrolebinding + app.kubernetes.io/part-of: neptune + name: neptune-proxy-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: neptune-proxy-role +subjects: +- kind: ServiceAccount + name: neptune-controller-manager + namespace: astra-connector +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: neptune + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: serviceaccount + app.kubernetes.io/part-of: neptune + name: neptune-resourcebackup +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: neptune-resourcebackup +subjects: +- kind: ServiceAccount + name: neptune-resourcebackup + namespace: astra-connector +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: neptune + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: serviceaccount + app.kubernetes.io/part-of: neptune + name: neptune-resourcedelete +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: neptune-resourcedelete +subjects: +- kind: ServiceAccount + name: neptune-resourcedelete + namespace: astra-connector +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: neptune + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: serviceaccount + app.kubernetes.io/part-of: neptune + name: neptune-resourcerestore +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: neptune-resourcerestore +subjects: +- kind: ServiceAccount + name: neptune-resourcerestore + namespace: astra-connector +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: neptune + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: serviceaccount + app.kubernetes.io/part-of: neptune + name: neptune-resourcesummaryupload +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: neptune-resourcesummaryupload +subjects: +- kind: ServiceAccount + name: neptune-resourcesummaryupload + namespace: astra-connector +--- +apiVersion: v1 +kind: Namespace +metadata: + labels: + control-plane: controller-manager + name: astra-connector-operator +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null + name: astraconnectors.astra.netapp.io +spec: + group: astra.netapp.io + names: + kind: AstraConnector + listKind: AstraConnectorList + plural: astraconnectors + singular: astraconnector + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.natsSyncClient.registered + name: Registered + type: string + - jsonPath: .status.natsSyncClient.astraClusterID + name: AstraClusterID + type: string + - jsonPath: .status.natsSyncClient.astraConnectorID + name: AstraConnectorID + type: string + - jsonPath: .status.natsSyncClient.status + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: AstraConnector is the Schema for the astraconnectors API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: AstraConnectorSpec defines the desired state of AstraConnector + properties: + astra: + properties: + accountId: + type: string + cloudId: + type: string + clusterId: + type: string + clusterName: + type: string + skipTLSValidation: + type: boolean + tokenRef: + type: string + unregister: + type: boolean + type: object + astraConnect: + properties: + image: + type: string + replicas: + default: 1 + format: int32 + type: integer + type: object + autoSupport: + default: + enrolled: true + url: https://stagesupport.netapp.com/put/AsupPut + description: AutoSupport indicates willingness to participate in NetApp's + proactive support application, NetApp Active IQ. An internet connection + is required (port 442) and all support data is anonymized. The default + election is true and indicates support data will be sent to NetApp. + An empty or blank election is the same as a default election. Air + gapped installations should enter false. + properties: + enrolled: + default: true + description: Enrolled determines if you want to send anonymous + data to NetApp for support purposes. + type: boolean + url: + default: https://stagesupport.netapp.com/put/AsupPut + description: URL determines where the anonymous data will be sent + type: string + type: object + imageRegistry: + properties: + name: + type: string + secret: + type: string + type: object + labels: + additionalProperties: + type: string + description: Labels any additional labels wanted to be added to resources + type: object + nats: + properties: + image: + type: string + replicas: + default: 1 + format: int32 + type: integer + type: object + natsSyncClient: + properties: + cloudBridgeURL: + type: string + hostAliasIP: + type: string + image: + type: string + replicas: + default: 1 + format: int32 + type: integer + type: object + neptune: + properties: + image: + type: string + type: object + skipPreCheck: + default: false + description: SkipPreCheck determines if you want to skip pre-checks + and go ahead with the installation. + type: boolean + type: object + status: + description: AstraConnectorStatus defines the observed state of AstraConnector + properties: + natsSyncClient: + description: NatsSyncClientStatus defines the observed state of NatsSyncClient + properties: + astraClusterID: + type: string + astraConnectorID: + type: string + registered: + type: string + status: + type: string + type: object + nodes: + items: + type: string + type: array + observedSpec: + description: ObservedSpec is the last observed Connector custom resource + spec + properties: + astra: + properties: + accountId: + type: string + cloudId: + type: string + clusterId: + type: string + clusterName: + type: string + skipTLSValidation: + type: boolean + tokenRef: + type: string + unregister: + type: boolean + type: object + astraConnect: + properties: + image: + type: string + replicas: + default: 1 + format: int32 + type: integer + type: object + autoSupport: + default: + enrolled: true + url: https://stagesupport.netapp.com/put/AsupPut + description: AutoSupport indicates willingness to participate + in NetApp's proactive support application, NetApp Active IQ. + An internet connection is required (port 442) and all support + data is anonymized. The default election is true and indicates + support data will be sent to NetApp. An empty or blank election + is the same as a default election. Air gapped installations + should enter false. + properties: + enrolled: + default: true + description: Enrolled determines if you want to send anonymous + data to NetApp for support purposes. + type: boolean + url: + default: https://stagesupport.netapp.com/put/AsupPut + description: URL determines where the anonymous data will + be sent + type: string + type: object + imageRegistry: + properties: + name: + type: string + secret: + type: string + type: object + labels: + additionalProperties: + type: string + description: Labels any additional labels wanted to be added to + resources + type: object + nats: + properties: + image: + type: string + replicas: + default: 1 + format: int32 + type: integer + type: object + natsSyncClient: + properties: + cloudBridgeURL: + type: string + hostAliasIP: + type: string + image: + type: string + replicas: + default: 1 + format: int32 + type: integer + type: object + neptune: + properties: + image: + type: string + type: object + skipPreCheck: + default: false + description: SkipPreCheck determines if you want to skip pre-checks + and go ahead with the installation. + type: boolean + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: operator-controller-manager + namespace: astra-connector-operator +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: operator-leader-election-role + namespace: astra-connector-operator +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: operator-manager-role +rules: +- nonResourceURLs: + - /metrics + verbs: + - get + - list + - watch +- apiGroups: + - "" + - apiextensions.k8s.io + - apps + - autoscaling + - batch + - crd.projectcalico.org + - extensions + - networking.k8s.io + - policy + - rbac.authorization.k8s.io + - security.openshift.io + - snapshot.storage.k8s.io + - storage.k8s.io + - trident.netapp.io + resources: + - configmaps + - cronjobs + - csidrivers + - csinodes + - customresourcedefinitions + - daemonsets + - deployments + - horizontalpodautoscalers + - ingresses + - jobs + - namespaces + - networkpolicies + - persistentvolumeclaims + - poddisruptionbudgets + - pods + - podsecuritypolicies + - podtemplates + - replicasets + - replicationcontrollers + - replicationcontrollers/scale + - rolebindings + - roles + - secrets + - securitycontextconstraints + - serviceaccounts + - services + - statefulsets + - storageclasses + - tridentbackends + - tridentmirrorrelationships + - tridentnodes + - tridentsnapshotinfos + - tridentversions + - tridentvolumes + - volumesnapshotcontents + - volumesnapshots + verbs: + - create + - delete + - get + - list + - patch + - update + - use + - watch +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' +- apiGroups: + - astra.netapp.io + resources: + - astraconnectors + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - astra.netapp.io + resources: + - astraconnectors/finalizers + verbs: + - update +- apiGroups: + - astra.netapp.io + resources: + - astraconnectors/status + verbs: + - get + - patch + - update +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: operator-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: operator-proxy-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: operator-leader-election-rolebinding + namespace: astra-connector-operator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: operator-leader-election-role +subjects: +- kind: ServiceAccount + name: operator-controller-manager + namespace: astra-connector-operator +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: operator-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: operator-manager-role +subjects: +- kind: ServiceAccount + name: operator-controller-manager + namespace: astra-connector-operator +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: operator-proxy-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: operator-proxy-role +subjects: +- kind: ServiceAccount + name: operator-controller-manager + namespace: astra-connector-operator +--- +apiVersion: v1 +data: + controller_manager_config.yaml: | + apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 + kind: ControllerManagerConfig + health: + healthProbeBindAddress: :8081 + metrics: + bindAddress: 127.0.0.1:8080 + webhook: + port: 9443 + leaderElection: + leaderElect: true + resourceName: c3ec164e.netapp.io +kind: ConfigMap +metadata: + name: operator-manager-config + namespace: astra-connector-operator +--- +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: controller-manager + name: operator-controller-manager-metrics-service + namespace: astra-connector-operator +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: https + selector: + control-plane: controller-manager +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + seccomp.security.alpha.kubernetes.io/pod: runtime/default + labels: + control-plane: controller-manager + name: operator-controller-manager + namespace: astra-connector-operator +spec: + replicas: 1 + selector: + matchLabels: + control-plane: controller-manager + template: + metadata: + labels: + app: operator.connector.netapp.io + control-plane: controller-manager + spec: + containers: + - args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=10 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.14.1 + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + protocol: TCP + securityContext: + seccompProfile: + type: RuntimeDefault + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=127.0.0.1:8080 + - --leader-elect + command: + - /manager + image: netapp/astra-connector-operator:3.0.0-202404050608 + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 300m + memory: 750Mi + requests: + cpu: 100m + memory: 75Mi + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsGroup: 20000 + runAsNonRoot: true + runAsUser: 10001 + seccompProfile: + type: RuntimeDefault + serviceAccountName: operator-controller-manager + terminationGracePeriodSeconds: 10 diff --git a/details/operator-sdk/controllers/astraconnector_controller.go b/details/operator-sdk/controllers/astraconnector_controller.go index 450906ab..38efcb1d 100644 --- a/details/operator-sdk/controllers/astraconnector_controller.go +++ b/details/operator-sdk/controllers/astraconnector_controller.go @@ -219,16 +219,6 @@ func (r *AstraConnectorController) Reconcile(ctx context.Context, req ctrl.Reque } } - if natsSyncClientStatus.AstraClusterId != "" { - log.Info(fmt.Sprintf("Updating CR status, clusterID: '%s'", natsSyncClientStatus.AstraClusterId)) - } - - _ = r.updateAstraConnectorStatus(ctx, astraConnector, natsSyncClientStatus, true) - err := r.waitForStatusUpdate(astraConnector, log) - if err != nil { - log.Error(err, "Failed to update status, ignoring since this will be fixed on a future reconcile.") - } - return ctrl.Result{}, nil } else { diff --git a/details/operator-sdk/controllers/connector.go b/details/operator-sdk/controllers/connector.go index 91ef5d2e..6a83a45a 100644 --- a/details/operator-sdk/controllers/connector.go +++ b/details/operator-sdk/controllers/connector.go @@ -3,23 +3,17 @@ package controllers import ( "context" "fmt" - "net/http" - "strings" "time" "github.com/NetApp-Polaris/astra-connector-operator/details/k8s" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" ctrllog "sigs.k8s.io/controller-runtime/pkg/log" "github.com/NetApp-Polaris/astra-connector-operator/app/conf" "github.com/NetApp-Polaris/astra-connector-operator/app/deployer/connector" "github.com/NetApp-Polaris/astra-connector-operator/app/deployer/model" - "github.com/NetApp-Polaris/astra-connector-operator/app/register" - "github.com/NetApp-Polaris/astra-connector-operator/common" v1 "github.com/NetApp-Polaris/astra-connector-operator/details/operator-sdk/api/v1" ) @@ -39,129 +33,17 @@ func (r *AstraConnectorController) deployConnector(ctx context.Context, } } - k8sUtil := k8s.NewK8sUtil(r.Client, r.Clientset, log) - - // Let's register the cluster now - registerUtil := register.NewClusterRegisterUtil(astraConnector, &http.Client{}, r.Client, k8sUtil, log, context.Background()) - registered := false - log.Info("Checking for natsSyncClient configmap") - foundCM := &corev1.ConfigMap{} - astraConnectorID := "" - err := r.Get(ctx, types.NamespacedName{Name: common.NatsSyncClientConfigMapName, Namespace: astraConnector.Namespace}, foundCM) - if err != nil { - return ctrl.Result{RequeueAfter: time.Minute * conf.Config.ErrorTimeout()}, err - } - if len(foundCM.Data) != 0 { - registered = true - astraConnectorID, err = registerUtil.GetConnectorIDFromConfigMap(foundCM.Data) - if err != nil { - log.Error(err, FailedLocationIDGet) - natsSyncClientStatus.Status = FailedLocationIDGet - _ = r.updateAstraConnectorStatus(ctx, astraConnector, *natsSyncClientStatus) - return ctrl.Result{RequeueAfter: time.Minute * conf.Config.ErrorTimeout()}, err - } - if astraConnectorID == "" { - log.Error(err, EmptyLocationIDGet) - natsSyncClientStatus.Status = EmptyLocationIDGet - _ = r.updateAstraConnectorStatus(ctx, astraConnector, *natsSyncClientStatus) - return ctrl.Result{RequeueAfter: time.Minute * conf.Config.ErrorTimeout()}, err - } - } - - // RegisterClient - if !astraConnector.Spec.Astra.Unregister { - // Check the feature flag first - if conf.Config.FeatureFlags().SkipAstraRegistration() { - log.Info("Skipping Nats and Astra registration, feature flag set to not register") - natsSyncClientStatus.Status = DeployedComponents - _ = r.updateAstraConnectorStatus(ctx, astraConnector, *natsSyncClientStatus) - return ctrl.Result{RequeueAfter: time.Minute * conf.Config.ErrorTimeout()}, nil - } - - if registered { - log.Info("natsSyncClient already registered", "astraConnectorID", astraConnectorID) - } else { - log.Info("Registering natsSyncClient") - var errorReason string - astraConnectorID, errorReason, err = registerUtil.RegisterNatsSyncClient() - if err != nil { - log.Error(err, FailedRegisterNSClient) - natsSyncClientStatus.Status = errorReason - _ = r.updateAstraConnectorStatus(ctx, astraConnector, *natsSyncClientStatus) - return ctrl.Result{RequeueAfter: time.Minute * conf.Config.ErrorTimeout()}, err - } - - log.Info("natsSyncClient ConnectorID", "astraConnectorID", astraConnectorID) - } - natsSyncClientStatus.AstraConnectorID = astraConnectorID - natsSyncClientStatus.Status = RegisterNSClient - - if astraConnector.Spec.Astra.TokenRef == "" || astraConnector.Spec.Astra.AccountId == "" || astraConnector.Spec.Astra.ClusterName == "" { - log.Info("Skipping cluster registration with Astra, incomplete Astra details provided TokenRef/AccountId/ClusterName") - } else { - log.Info("Registering cluster with Astra") - - // Check if there is a cluster ID from: - // 1. CR Status. If it is in hear it means we have already been through this loop once and know what the ID is - // 2. Check the CR Spec. If it is in here, use it. It will be validated later. - // 3. If the clusterID is in neither of the above, leave it "" and the operator will create one and populate the status - // 4. Save the clusterID to the CR Status - var clusterId string - if strings.TrimSpace(natsSyncClientStatus.AstraClusterId) != "" { - clusterId = natsSyncClientStatus.AstraClusterId - log.WithValues("clusterID", clusterId).Info("using clusterID from CR Status") - } else { - clusterId = astraConnector.Spec.Astra.ClusterId - } - - var errorReason string - natsSyncClientStatus.AstraClusterId, errorReason, err = registerUtil.RegisterClusterWithAstra(astraConnectorID, clusterId) - if err != nil { - log.Error(err, FailedConnectorIDAdd) - natsSyncClientStatus.Status = errorReason - _ = r.updateAstraConnectorStatus(ctx, astraConnector, *natsSyncClientStatus) - return ctrl.Result{RequeueAfter: time.Minute * conf.Config.ErrorTimeout()}, err - } - log.Info("Registered cluster with Astra") - } - natsSyncClientStatus.Registered = "true" - natsSyncClientStatus.Status = RegisteredWithAstra - } else { - if registered { - log.Info("Unregistering natsSyncClient") - err = registerUtil.UnRegisterNatsSyncClient() - if err != nil { - log.Error(err, FailedUnRegisterNSClient) - natsSyncClientStatus.Status = FailedUnRegisterNSClient - _ = r.updateAstraConnectorStatus(ctx, astraConnector, *natsSyncClientStatus) - return ctrl.Result{RequeueAfter: time.Minute * conf.Config.ErrorTimeout()}, err - } - log.Info(UnregisterNSClient) - } else { - log.Info("Already unregistered with Astra") - } - natsSyncClientStatus.Registered = "false" - natsSyncClientStatus.AstraConnectorID = "" - natsSyncClientStatus.Status = UnregisterNSClient - } - - // if we are registered and have a clusterid let's set up the asup cr - if natsSyncClientStatus.Registered == "true" && natsSyncClientStatus.AstraClusterId != "" { - err = r.createASUPCR(ctx, astraConnector, natsSyncClientStatus.AstraClusterId) - if err != nil { - log.Error(err, FailedASUPCreation) - natsSyncClientStatus.Status = FailedASUPCreation - _ = r.updateAstraConnectorStatus(ctx, astraConnector, *natsSyncClientStatus) - return ctrl.Result{RequeueAfter: time.Minute * conf.Config.ErrorTimeout()}, err - } - } + natsSyncClientStatus.Registered = "true" + natsSyncClientStatus.AstraConnectorID = "1969" + natsSyncClientStatus.Status = RegisteredWithAstra + _ = r.updateAstraConnectorStatus(ctx, astraConnector, *natsSyncClientStatus) // No need to requeue due to success return ctrl.Result{}, nil } func getDeployers() []model.Deployer { - return []model.Deployer{connector.NewNatsDeployer(), connector.NewNatsSyncClientDeployer(), connector.NewAstraConnectorDeployer()} + return []model.Deployer{connector.NewAstraConnectorDeployer()} } func (r *AstraConnectorController) deleteConnectorClusterScopedResources(ctx context.Context, astraConnector *v1.AstraConnector) {