From 762efe6e87a814913f14aa06c94c78c63d394972 Mon Sep 17 00:00:00 2001 From: Neha Vellanki <35039892+neha-vellanki12@users.noreply.github.com> Date: Thu, 14 Sep 2023 20:28:44 -0700 Subject: [PATCH] adding RestorePlan to Backup for GKE (#8803) * adding RestorePlan to Backup for GKE * fixed spacing issue * fixed more spacing issue * adding newline end of file * fixed trailing spaces * fixed test file names * added test gaps * adding description adn labels * fixed tests * fixed protected application name length * fixed protected app test * fix restore all namespaces test names * removed bp prefix from resource names * removed last bp ref --- mmv1/products/gkebackup/RestorePlan.yaml | 455 ++++++++++++++++++ ...p_restoreplan_all_cluster_resources.tf.erb | 39 ++ ...kebackup_restoreplan_all_namespaces.tf.erb | 40 ++ ...p_restoreplan_protected_application.tf.erb | 44 ++ ...backup_restoreplan_rename_namespace.tf.erb | 66 +++ ...ckup_restoreplan_rollback_namespace.tf.erb | 49 ++ ...p_restoreplan_second_transformation.tf.erb | 64 +++ 7 files changed, 757 insertions(+) create mode 100644 mmv1/products/gkebackup/RestorePlan.yaml create mode 100644 mmv1/templates/terraform/examples/gkebackup_restoreplan_all_cluster_resources.tf.erb create mode 100644 mmv1/templates/terraform/examples/gkebackup_restoreplan_all_namespaces.tf.erb create mode 100644 mmv1/templates/terraform/examples/gkebackup_restoreplan_protected_application.tf.erb create mode 100644 mmv1/templates/terraform/examples/gkebackup_restoreplan_rename_namespace.tf.erb create mode 100644 mmv1/templates/terraform/examples/gkebackup_restoreplan_rollback_namespace.tf.erb create mode 100644 mmv1/templates/terraform/examples/gkebackup_restoreplan_second_transformation.tf.erb diff --git a/mmv1/products/gkebackup/RestorePlan.yaml b/mmv1/products/gkebackup/RestorePlan.yaml new file mode 100644 index 000000000000..b457a450fcb2 --- /dev/null +++ b/mmv1/products/gkebackup/RestorePlan.yaml @@ -0,0 +1,455 @@ +# Copyright 2023 Google Inc. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +--- !ruby/object:Api::Resource +name: 'RestorePlan' +base_url: 'projects/{{project}}/locations/{{location}}/restorePlans' +create_url: projects/{{project}}/locations/{{location}}/restorePlans?restorePlanId={{name}} +update_verb: :PATCH +update_mask: true +description: | + Represents a Restore Plan instance. +references: !ruby/object:Api::Resource::ReferenceLinks + guides: + 'Official Documentation': 'https://cloud.google.com/kubernetes-engine/docs/add-on/backup-for-gke' + api: 'https://cloud.google.com/kubernetes-engine/docs/add-on/backup-for-gke/reference/rest/v1/projects.locations.restorePlans' +iam_policy: !ruby/object:Api::Resource::IamPolicy + method_name_separator: ':' + parent_resource_attribute: 'name' + base_url: projects/{{project}}/locations/{{location}}/restorePlans/{{name}} + import_format: + [ + 'projects/{{project}}/locations/{{location}}/restorePlans/{{name}}', + '{{name}}', + ] +timeouts: !ruby/object:Api::Timeouts +autogen_async: true +examples: + - !ruby/object:Provider::Terraform::Examples + name: 'gkebackup_restoreplan_all_namespaces' + primary_resource_id: 'all_ns' + primary_resource_name: "fmt.Sprintf(\"tf-test-restore-all-ns%s\", + context[\"random_suffix\"\ + ])" + vars: + name: 'restore-all-ns' + test_env_vars: + project: :PROJECT_NAME + - !ruby/object:Provider::Terraform::Examples + name: 'gkebackup_restoreplan_rollback_namespace' + primary_resource_id: 'rollback_ns' + vars: + name: 'rollback-ns' + test_env_vars: + project: :PROJECT_NAME + - !ruby/object:Provider::Terraform::Examples + name: 'gkebackup_restoreplan_protected_application' + primary_resource_id: 'rollback_app' + vars: + name: 'rollback-app' + test_env_vars: + project: :PROJECT_NAME + - !ruby/object:Provider::Terraform::Examples + name: 'gkebackup_restoreplan_all_cluster_resources' + primary_resource_id: 'all_cluster_resources' + vars: + name: 'all-groupkinds' + test_env_vars: + project: :PROJECT_NAME + - !ruby/object:Provider::Terraform::Examples + name: 'gkebackup_restoreplan_rename_namespace' + primary_resource_id: 'rename_ns' + vars: + name: 'rename-ns' + test_env_vars: + project: :PROJECT_NAME + - !ruby/object:Provider::Terraform::Examples + name: 'gkebackup_restoreplan_second_transformation' + primary_resource_id: 'transform_rule' + vars: + name: 'transform-rule' + test_env_vars: + project: :PROJECT_NAME +skip_sweeper: true +parameters: + - !ruby/object:Api::Type::String + name: 'location' + url_param_only: true + required: true + immutable: true + description: | + The region of the Restore Plan. +properties: + - !ruby/object:Api::Type::String + name: name + required: true + immutable: true + description: | + The full name of the BackupPlan Resource. + custom_expand: 'templates/terraform/custom_expand/shortname_to_url.go.erb' + custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb' + - !ruby/object:Api::Type::String + name: uid + output: true + description: | + Server generated, unique identifier of UUID format. + - !ruby/object:Api::Type::String + name: description + description: | + User specified descriptive string for this RestorePlan. + - !ruby/object:Api::Type::KeyValuePairs + name: labels + description: | + Description: A set of custom labels supplied by the user. + A list of key->value pairs. + Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }. + - !ruby/object:Api::Type::String + name: 'backupPlan' + required: true + immutable: true + description: | + A reference to the BackupPlan from which Backups may be used + as the source for Restores created via this RestorePlan. + - !ruby/object:Api::Type::String + name: 'cluster' + required: true + immutable: true + description: | + The source cluster from which Restores will be created via this RestorePlan. + - !ruby/object:Api::Type::NestedObject + name: restoreConfig + required: true + description: | + Defines the configuration of Restores created via this RestorePlan. + properties: + - !ruby/object:Api::Type::Boolean + name: allNamespaces + description: | + If True, restore all namespaced resources in the Backup. + Setting this field to False will result in an error. + exactly_one_of: + - restoreConfig.0.allNamespaces + - restoreConfig.0.excludedNamespaces + - restoreConfig.0.selectedNamespaces + - restoreConfig.0.selectedApplications + - restoreConfig.0.noNamespaces + - !ruby/object:Api::Type::NestedObject + name: excludedNamespaces + description: | + A list of selected namespaces excluded from restoration. + All namespaces except those in this list will be restored. + exactly_one_of: + - restoreConfig.0.allNamespaces + - restoreConfig.0.excludedNamespaces + - restoreConfig.0.selectedNamespaces + - restoreConfig.0.selectedApplications + - restoreConfig.0.noNamespaces + properties: + - !ruby/object:Api::Type::Array + name: namespaces + required: true + description: | + A list of Kubernetes Namespaces. + item_type: Api::Type::String + - !ruby/object:Api::Type::NestedObject + name: selectedNamespaces + description: | + A list of selected namespaces to restore from the Backup. + The listed Namespaces and all resources contained in them will be restored. + exactly_one_of: + - restoreConfig.0.allNamespaces + - restoreConfig.0.excludedNamespaces + - restoreConfig.0.selectedNamespaces + - restoreConfig.0.selectedApplications + - restoreConfig.0.noNamespaces + properties: + - !ruby/object:Api::Type::Array + name: namespaces + required: true + description: | + A list of Kubernetes Namespaces. + item_type: Api::Type::String + - !ruby/object:Api::Type::NestedObject + name: selectedApplications + description: | + A list of selected ProtectedApplications to restore. + The listed ProtectedApplications and all the resources + to which they refer will be restored. + exactly_one_of: + - restoreConfig.0.allNamespaces + - restoreConfig.0.excludedNamespaces + - restoreConfig.0.selectedNamespaces + - restoreConfig.0.selectedApplications + - restoreConfig.0.noNamespaces + properties: + - !ruby/object:Api::Type::Array + name: namespacedNames + required: true + description: | + A list of namespaced Kubernetes resources. + item_type: !ruby/object:Api::Type::NestedObject + properties: + - !ruby/object:Api::Type::String + name: namespace + required: true + description: | + The namespace of a Kubernetes Resource. + - !ruby/object:Api::Type::String + name: name + required: true + description: | + The name of a Kubernetes Resource. + - !ruby/object:Api::Type::Boolean + name: noNamespaces + description: | + Do not restore any namespaced resources if set to "True". + Specifying this field to "False" is not allowed. + exactly_one_of: + - restoreConfig.0.allNamespaces + - restoreConfig.0.excludedNamespaces + - restoreConfig.0.selectedNamespaces + - restoreConfig.0.selectedApplications + - restoreConfig.0.noNamespaces + - !ruby/object:Api::Type::Enum + name: namespacedResourceRestoreMode + description: | + Defines the behavior for handling the situation where sets of namespaced resources + being restored already exist in the target cluster. + This MUST be set to a value other than `NAMESPACED_RESOURCE_RESTORE_MODE_UNSPECIFIED` + if the `namespacedResourceRestoreScope` is anything other than `noNamespaces`. + See https://cloud.google.com/kubernetes-engine/docs/add-on/backup-for-gke/reference/rest/v1/RestoreConfig#namespacedresourcerestoremode + for more information on each mode. + values: + - :DELETE_AND_RESTORE + - :FAIL_ON_CONFLICT + - !ruby/object:Api::Type::Enum + name: volumeDataRestorePolicy + description: | + Specifies the mechanism to be used to restore volume data. + This should be set to a value other than `NAMESPACED_RESOURCE_RESTORE_MODE_UNSPECIFIED` + if the `namespacedResourceRestoreScope` is anything other than `noNamespaces`. + If not specified, it will be treated as `NO_VOLUME_DATA_RESTORATION`. + See https://cloud.google.com/kubernetes-engine/docs/add-on/backup-for-gke/reference/rest/v1/RestoreConfig#VolumeDataRestorePolicy + for more information on each policy option. + values: + - :RESTORE_VOLUME_DATA_FROM_BACKUP + - :REUSE_VOLUME_HANDLE_FROM_BACKUP + - :NO_VOLUME_DATA_RESTORATION + - !ruby/object:Api::Type::NestedObject + name: clusterResourceRestoreScope + description: | + Identifies the cluster-scoped resources to restore from the Backup. + properties: + - !ruby/object:Api::Type::Boolean + name: allGroupKinds + description: | + If True, all valid cluster-scoped resources will be restored. + Mutually exclusive to any other field in `clusterResourceRestoreScope`. + exactly_one_of: + - restoreConfig.0.clusterResourceRestoreScope.0.allGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.excludedGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.selectedGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.noGroupKinds + - !ruby/object:Api::Type::Array + name: excludedGroupKinds + description: | + A list of cluster-scoped resource group kinds to NOT restore from the backup. + If specified, all valid cluster-scoped resources will be restored except + for those specified in the list. + Mutually exclusive to any other field in `clusterResourceRestoreScope`. + exactly_one_of: + - restoreConfig.0.clusterResourceRestoreScope.0.allGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.excludedGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.selectedGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.noGroupKinds + item_type: !ruby/object:Api::Type::NestedObject + required: true + properties: + - !ruby/object:Api::Type::String + name: resourceGroup + description: | + API Group string of a Kubernetes resource, e.g. + "apiextensions.k8s.io", "storage.k8s.io", etc. + Use empty string for core group. + - !ruby/object:Api::Type::String + name: resourceKind + description: | + Kind of a Kubernetes resource, e.g. + "CustomResourceDefinition", "StorageClass", etc. + - !ruby/object:Api::Type::Array + name: selectedGroupKinds + description: | + A list of cluster-scoped resource group kinds to restore from the backup. + If specified, only the selected resources will be restored. + Mutually exclusive to any other field in the `clusterResourceRestoreScope`. + exactly_one_of: + - restoreConfig.0.clusterResourceRestoreScope.0.allGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.excludedGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.selectedGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.noGroupKinds + item_type: !ruby/object:Api::Type::NestedObject + required: true + properties: + - !ruby/object:Api::Type::String + name: resourceGroup + description: | + API Group string of a Kubernetes resource, e.g. + "apiextensions.k8s.io", "storage.k8s.io", etc. + Use empty string for core group. + - !ruby/object:Api::Type::String + name: resourceKind + description: | + Kind of a Kubernetes resource, e.g. + "CustomResourceDefinition", "StorageClass", etc. + - !ruby/object:Api::Type::Boolean + name: noGroupKinds + description: | + If True, no cluster-scoped resources will be restored. + Mutually exclusive to any other field in `clusterResourceRestoreScope`. + exactly_one_of: + - restoreConfig.0.clusterResourceRestoreScope.0.allGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.excludedGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.selectedGroupKinds + - restoreConfig.0.clusterResourceRestoreScope.0.noGroupKinds + - !ruby/object:Api::Type::Enum + name: clusterResourceConflictPolicy + description: | + Defines the behavior for handling the situation where cluster-scoped resources + being restored already exist in the target cluster. + This MUST be set to a value other than `CLUSTER_RESOURCE_CONFLICT_POLICY_UNSPECIFIED` + if `clusterResourceRestoreScope` is anyting other than `noGroupKinds`. + See https://cloud.google.com/kubernetes-engine/docs/add-on/backup-for-gke/reference/rest/v1/RestoreConfig#clusterresourceconflictpolicy + for more information on each policy option. + values: + - :USE_EXISTING_VERSION + - :USE_BACKUP_VERSION + - !ruby/object:Api::Type::Array + name: transformationRules + description: | + A list of transformation rules to be applied against Kubernetes + resources as they are selected for restoration from a Backup. + Rules are executed in order defined - this order matters, + as changes made by a rule may impact the filtering logic of subsequent + rules. An empty list means no transformation will occur. + item_type: !ruby/object:Api::Type::NestedObject + required: true + description: | + A transformation rule to be applied against Kubernetes resources + as they are selected for restoration from a Backup. + A rule contains both filtering logic + (which resources are subject to transform) and transformation logic. + properties: + - !ruby/object:Api::Type::String + name: description + description: | + The description is a user specified string description + of the transformation rule. + - !ruby/object:Api::Type::NestedObject + name: resourceFilter + description: | + This field is used to specify a set of fields that should be used to + determine which resources in backup should be acted upon by the + supplied transformation rule actions, and this will ensure that only + specific resources are affected by transformation rule actions. + properties: + - !ruby/object:Api::Type::Array + name: namespaces + description: | + (Filtering parameter) Any resource subject to transformation must + be contained within one of the listed Kubernetes Namespace in the + Backup. If this field is not provided, no namespace filtering will + be performed (all resources in all Namespaces, including all + cluster-scoped resources, will be candidates for transformation). + To mix cluster-scoped and namespaced resources in the same rule, + use an empty string ("") as one of the target namespaces. + item_type: Api::Type::String + - !ruby/object:Api::Type::Array + name: groupKinds + description: | + (Filtering parameter) Any resource subject to transformation must + belong to one of the listed "types". If this field is not provided, + no type filtering will be performed + (all resources of all types matching previous filtering parameters + will be candidates for transformation). + item_type: !ruby/object:Api::Type::NestedObject + required: true + properties: + - !ruby/object:Api::Type::String + name: resourceGroup + description: | + API Group string of a Kubernetes resource, e.g. + "apiextensions.k8s.io", "storage.k8s.io", etc. + Use empty string for core group. + - !ruby/object:Api::Type::String + name: resourceKind + description: | + Kind of a Kubernetes resource, e.g. + "CustomResourceDefinition", "StorageClass", etc. + - !ruby/object:Api::Type::String + name: jsonPath + description: | + This is a JSONPath expression that matches specific fields of + candidate resources and it operates as a filtering parameter + (resources that are not matched with this expression will not + be candidates for transformation). + - !ruby/object:Api::Type::Array + name: fieldActions + required: true + description: | + A list of transformation rule actions to take against candidate + resources. Actions are executed in order defined - this order + matters, as they could potentially interfere with each other and + the first operation could affect the outcome of the second operation. + item_type: !ruby/object:Api::Type::NestedObject + required: true + description: | + TransformationRuleAction defines a TransformationRule action + based on the JSON Patch RFC (https://www.rfc-editor.org/rfc/rfc6902) + properties: + - !ruby/object:Api::Type::Enum + name: op + required: true + description: | + Specifies the operation to perform. + values: + - :REMOVE + - :MOVE + - :COPY + - :ADD + - :TEST + - :REPLACE + - !ruby/object:Api::Type::String + name: fromPath + description: | + A string containing a JSON Pointer value that references the + location in the target document to move the value from. + - !ruby/object:Api::Type::String + name: path + description: | + A string containing a JSON-Pointer value that references a + location within the target document where the operation is performed. + - !ruby/object:Api::Type::String + name: value + description: | + A string that specifies the desired value in string format + to use for transformation. + - !ruby/object:Api::Type::String + name: state + output: true + description: | + The State of the RestorePlan. + - !ruby/object:Api::Type::String + name: stateReason + output: true + description: | + Detailed description of why RestorePlan is in its current state. diff --git a/mmv1/templates/terraform/examples/gkebackup_restoreplan_all_cluster_resources.tf.erb b/mmv1/templates/terraform/examples/gkebackup_restoreplan_all_cluster_resources.tf.erb new file mode 100644 index 000000000000..4578aba10489 --- /dev/null +++ b/mmv1/templates/terraform/examples/gkebackup_restoreplan_all_cluster_resources.tf.erb @@ -0,0 +1,39 @@ +resource "google_container_cluster" "primary" { + name = "<%= ctx[:vars]['name'] %>-cluster" + location = "us-central1" + initial_node_count = 1 + workload_identity_config { + workload_pool = "<%= ctx[:test_env_vars]['project'] %>.svc.id.goog" + } + addons_config { + gke_backup_agent_config { + enabled = true + } + } +} + +resource "google_gke_backup_backup_plan" "basic" { + name = "<%= ctx[:vars]['name'] %>" + cluster = google_container_cluster.primary.id + location = "us-central1" + backup_config { + include_volume_data = true + include_secrets = true + all_namespaces = true + } +} + +resource "google_gke_backup_restore_plan" "all_cluster_resources" { + name = "<%= ctx[:vars]['name'] %>-rp" + location = "us-central1" + backup_plan = google_gke_backup_backup_plan.basic.id + cluster = google_container_cluster.primary.id + restore_config { + no_namespaces = true + namespaced_resource_restore_mode = "FAIL_ON_CONFLICT" + cluster_resource_restore_scope { + all_group_kinds = true + } + cluster_resource_conflict_policy = "USE_EXISTING_VERSION" + } +} diff --git a/mmv1/templates/terraform/examples/gkebackup_restoreplan_all_namespaces.tf.erb b/mmv1/templates/terraform/examples/gkebackup_restoreplan_all_namespaces.tf.erb new file mode 100644 index 000000000000..94c5d25f55ba --- /dev/null +++ b/mmv1/templates/terraform/examples/gkebackup_restoreplan_all_namespaces.tf.erb @@ -0,0 +1,40 @@ +resource "google_container_cluster" "primary" { + name = "<%= ctx[:vars]['name'] %>-cluster" + location = "us-central1" + initial_node_count = 1 + workload_identity_config { + workload_pool = "<%= ctx[:test_env_vars]['project'] %>.svc.id.goog" + } + addons_config { + gke_backup_agent_config { + enabled = true + } + } +} + +resource "google_gke_backup_backup_plan" "basic" { + name = "<%= ctx[:vars]['name'] %>" + cluster = google_container_cluster.primary.id + location = "us-central1" + backup_config { + include_volume_data = true + include_secrets = true + all_namespaces = true + } +} + +resource "google_gke_backup_restore_plan" "all_ns" { + name = "<%= ctx[:vars]['name'] %>" + location = "us-central1" + backup_plan = google_gke_backup_backup_plan.basic.id + cluster = google_container_cluster.primary.id + restore_config { + all_namespaces = true + namespaced_resource_restore_mode = "FAIL_ON_CONFLICT" + volume_data_restore_policy = "RESTORE_VOLUME_DATA_FROM_BACKUP" + cluster_resource_restore_scope { + all_group_kinds = true + } + cluster_resource_conflict_policy = "USE_EXISTING_VERSION" + } +} \ No newline at end of file diff --git a/mmv1/templates/terraform/examples/gkebackup_restoreplan_protected_application.tf.erb b/mmv1/templates/terraform/examples/gkebackup_restoreplan_protected_application.tf.erb new file mode 100644 index 000000000000..64585c3f89a0 --- /dev/null +++ b/mmv1/templates/terraform/examples/gkebackup_restoreplan_protected_application.tf.erb @@ -0,0 +1,44 @@ +resource "google_container_cluster" "primary" { + name = "<%= ctx[:vars]['name'] %>-cluster" + location = "us-central1" + initial_node_count = 1 + workload_identity_config { + workload_pool = "<%= ctx[:test_env_vars]['project'] %>.svc.id.goog" + } + addons_config { + gke_backup_agent_config { + enabled = true + } + } +} + +resource "google_gke_backup_backup_plan" "basic" { + name = "<%= ctx[:vars]['name'] %>" + cluster = google_container_cluster.primary.id + location = "us-central1" + backup_config { + include_volume_data = true + include_secrets = true + all_namespaces = true + } +} + +resource "google_gke_backup_restore_plan" "rollback_app" { + name = "<%= ctx[:vars]['name'] %>-rp" + location = "us-central1" + backup_plan = google_gke_backup_backup_plan.basic.id + cluster = google_container_cluster.primary.id + restore_config { + selected_applications { + namespaced_names { + name = "my-app" + namespace = "my-ns" + } + } + namespaced_resource_restore_mode = "DELETE_AND_RESTORE" + volume_data_restore_policy = "REUSE_VOLUME_HANDLE_FROM_BACKUP" + cluster_resource_restore_scope { + no_group_kinds = true + } + } +} diff --git a/mmv1/templates/terraform/examples/gkebackup_restoreplan_rename_namespace.tf.erb b/mmv1/templates/terraform/examples/gkebackup_restoreplan_rename_namespace.tf.erb new file mode 100644 index 000000000000..11179e2afee6 --- /dev/null +++ b/mmv1/templates/terraform/examples/gkebackup_restoreplan_rename_namespace.tf.erb @@ -0,0 +1,66 @@ +resource "google_container_cluster" "primary" { + name = "<%= ctx[:vars]['name'] %>-cluster" + location = "us-central1" + initial_node_count = 1 + workload_identity_config { + workload_pool = "<%= ctx[:test_env_vars]['project'] %>.svc.id.goog" + } + addons_config { + gke_backup_agent_config { + enabled = true + } + } +} + +resource "google_gke_backup_backup_plan" "basic" { + name = "<%= ctx[:vars]['name'] %>" + cluster = google_container_cluster.primary.id + location = "us-central1" + backup_config { + include_volume_data = true + include_secrets = true + all_namespaces = true + } +} + +resource "google_gke_backup_restore_plan" "rename_ns" { + name = "<%= ctx[:vars]['name'] %>-rp" + location = "us-central1" + backup_plan = google_gke_backup_backup_plan.basic.id + cluster = google_container_cluster.primary.id + restore_config { + selected_namespaces { + namespaces = ["ns1"] + } + namespaced_resource_restore_mode = "FAIL_ON_CONFLICT" + volume_data_restore_policy = "REUSE_VOLUME_HANDLE_FROM_BACKUP" + cluster_resource_restore_scope { + no_group_kinds = true + } + transformation_rules { + description = "rename namespace from ns1 to ns2" + resource_filter { + group_kinds { + resource_kind = "Namespace" + } + json_path = ".metadata[?(@.name == 'ns1')]" + } + field_actions { + op = "REPLACE" + path = "/metadata/name" + value = "ns2" + } + } + transformation_rules { + description = "move all resources from ns1 to ns2" + resource_filter { + namespaces = ["ns1"] + } + field_actions { + op = "REPLACE" + path = "/metadata/namespace" + value = "ns2" + } + } + } +} \ No newline at end of file diff --git a/mmv1/templates/terraform/examples/gkebackup_restoreplan_rollback_namespace.tf.erb b/mmv1/templates/terraform/examples/gkebackup_restoreplan_rollback_namespace.tf.erb new file mode 100644 index 000000000000..e2b76bae6d28 --- /dev/null +++ b/mmv1/templates/terraform/examples/gkebackup_restoreplan_rollback_namespace.tf.erb @@ -0,0 +1,49 @@ +resource "google_container_cluster" "primary" { + name = "<%= ctx[:vars]['name'] %>-cluster" + location = "us-central1" + initial_node_count = 1 + workload_identity_config { + workload_pool = "<%= ctx[:test_env_vars]['project'] %>.svc.id.goog" + } + addons_config { + gke_backup_agent_config { + enabled = true + } + } +} + +resource "google_gke_backup_backup_plan" "basic" { + name = "<%= ctx[:vars]['name'] %>" + cluster = google_container_cluster.primary.id + location = "us-central1" + backup_config { + include_volume_data = true + include_secrets = true + all_namespaces = true + } +} + +resource "google_gke_backup_restore_plan" "rollback_ns" { + name = "<%= ctx[:vars]['name'] %>-rp" + location = "us-central1" + backup_plan = google_gke_backup_backup_plan.basic.id + cluster = google_container_cluster.primary.id + restore_config { + selected_namespaces { + namespaces = ["my-ns"] + } + namespaced_resource_restore_mode = "DELETE_AND_RESTORE" + volume_data_restore_policy = "RESTORE_VOLUME_DATA_FROM_BACKUP" + cluster_resource_restore_scope { + selected_group_kinds { + resource_group = "apiextension.k8s.io" + resource_kind = "CustomResourceDefinition" + } + selected_group_kinds { + resource_group = "storage.k8s.io" + resource_kind = "StorageClass" + } + } + cluster_resource_conflict_policy = "USE_EXISTING_VERSION" + } +} diff --git a/mmv1/templates/terraform/examples/gkebackup_restoreplan_second_transformation.tf.erb b/mmv1/templates/terraform/examples/gkebackup_restoreplan_second_transformation.tf.erb new file mode 100644 index 000000000000..1392a5997f74 --- /dev/null +++ b/mmv1/templates/terraform/examples/gkebackup_restoreplan_second_transformation.tf.erb @@ -0,0 +1,64 @@ +resource "google_container_cluster" "primary" { + name = "<%= ctx[:vars]['name'] %>-cluster" + location = "us-central1" + initial_node_count = 1 + workload_identity_config { + workload_pool = "<%= ctx[:test_env_vars]['project'] %>.svc.id.goog" + } + addons_config { + gke_backup_agent_config { + enabled = true + } + } +} + +resource "google_gke_backup_backup_plan" "basic" { + name = "<%= ctx[:vars]['name'] %>" + cluster = google_container_cluster.primary.id + location = "us-central1" + backup_config { + include_volume_data = true + include_secrets = true + all_namespaces = true + } +} + +resource "google_gke_backup_restore_plan" "transform_rule" { + name = "<%= ctx[:vars]['name'] %>-rp" + description = "copy nginx env variables" + labels = { + "app" = "nginx" + } + location = "us-central1" + backup_plan = google_gke_backup_backup_plan.basic.id + cluster = google_container_cluster.primary.id + restore_config { + excluded_namespaces { + namespaces = ["my-ns"] + } + namespaced_resource_restore_mode = "DELETE_AND_RESTORE" + volume_data_restore_policy = "RESTORE_VOLUME_DATA_FROM_BACKUP" + cluster_resource_restore_scope { + excluded_group_kinds { + resource_group = "apiextension.k8s.io" + resource_kind = "CustomResourceDefinition" + } + } + cluster_resource_conflict_policy = "USE_EXISTING_VERSION" + transformation_rules { + description = "Copy environment variables from the nginx container to the install init container." + resource_filter { + group_kinds { + resource_kind = "Pod" + resource_group = "" + } + json_path = ".metadata[?(@.name == 'nginx')]" + } + field_actions { + op = "COPY" + path = "/spec/initContainers/0/env" + from_path = "/spec/containers/0/env" + } + } + } +}