-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new resource netapp volumes quotaRules (#12665)
- Loading branch information
Showing
4 changed files
with
506 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
# Copyright 2024 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. | ||
|
||
--- | ||
name: 'VolumeQuotaRule' | ||
api_resource_type_kind: QuotaRule | ||
description: | | ||
QuotaRule specifies the maximum capacity a user or group can use within a volume. They can be used for creating default and individual quota rules. | ||
references: | ||
guides: | ||
'Documentation': https://cloud.google.com/netapp/volumes/docs/configure-and-use/volumes/overview#volume_user_and_group_quotas | ||
api: https://cloud.google.com/netapp/volumes/docs/reference/rest/v1/projects.locations.volumes.quotaRules | ||
docs: | ||
base_url: 'projects/{{project}}/locations/{{location}}/volumes/{{volume_name}}/quotaRules' | ||
self_link: 'projects/{{project}}/locations/{{location}}/volumes/{{volume_name}}/quotaRules/{{name}}' | ||
create_url: 'projects/{{project}}/locations/{{location}}/volumes/{{volume_name}}/quotaRules?quotaRuleId={{name}}' | ||
update_url: 'projects/{{project}}/locations/{{location}}/volumes/{{volume_name}}/quotaRules/{{name}}' | ||
update_verb: 'PATCH' | ||
update_mask: true | ||
delete_url: 'projects/{{project}}/locations/{{location}}/volumes/{{volume_name}}/quotaRules/{{name}}' | ||
timeouts: | ||
insert_minutes: 20 | ||
update_minutes: 20 | ||
delete_minutes: 20 | ||
autogen_async: true | ||
async: | ||
actions: ['create', 'delete', 'update'] | ||
type: 'OpAsync' | ||
operation: | ||
base_url: '{{op_id}}' | ||
result: | ||
resource_inside_response: false | ||
custom_code: | ||
# Skipping the sweeper since we need to sweep multiple regions | ||
exclude_sweeper: true | ||
examples: | ||
- name: 'netapp_volume_quota_rule_basic' | ||
primary_resource_id: 'test_quota_rule' | ||
vars: | ||
volume_name: 'test-volume' | ||
pool_name: 'test-pool' | ||
network_name: 'test-network' | ||
quota_rule_name: 'test-volume-quota-rule' | ||
test_vars_overrides: | ||
'network_name': 'acctest.BootstrapSharedServiceNetworkingConnection(t, "gcnv-network-config-1", acctest.ServiceNetworkWithParentService("netapp.servicenetworking.goog"))' | ||
parameters: | ||
- name: 'location' | ||
type: String | ||
description: | | ||
Loction of the quotaRule. QuotaRules are child resources of volumes and live in the same location. | ||
url_param_only: true | ||
immutable: true | ||
- name: 'volume_name' | ||
type: String | ||
description: | | ||
Name of the volume to create the quotaRule in. | ||
url_param_only: true | ||
required: true | ||
immutable: true | ||
- name: 'name' | ||
type: String | ||
description: | ||
The resource name of the quotaRule. | ||
url_param_only: true | ||
required: true | ||
immutable: true | ||
properties: | ||
- name: 'target' | ||
type: String | ||
description: | | ||
The quota rule applies to the specified user or group. | ||
Valid targets for volumes with NFS protocol enabled: | ||
- UNIX UID for individual user quota | ||
- UNIX GID for individual group quota | ||
Valid targets for volumes with SMB protocol enabled: | ||
- Windows SID for individual user quota | ||
Leave empty for default quotas | ||
- name: 'type' | ||
type: Enum | ||
description: | | ||
Types of Quota Rule. | ||
required: true | ||
enum_values: | ||
- 'INDIVIDUAL_USER_QUOTA' | ||
- 'INDIVIDUAL_GROUP_QUOTA' | ||
- 'DEFAULT_USER_QUOTA' | ||
- 'DEFAULT_GROUP_QUOTA' | ||
- name: 'diskLimitMib' | ||
type: Integer | ||
description: | ||
The maximum allowed capacity in MiB. | ||
required: true | ||
- name: 'state' | ||
type: String | ||
description: | | ||
The state of the quota rule. Possible Values : [STATE_UNSPECIFIED, CREATING, UPDATING, READY, DELETING, ERROR] | ||
output: true | ||
- name: 'stateDetails' | ||
type: String | ||
description: | | ||
State details of the quota rule | ||
output: true | ||
- name: 'createTime' | ||
type: String | ||
description: | | ||
Create time of the quota rule. A timestamp in RFC3339 UTC "Zulu" format. Examples: "2023-06-22T09:13:01.617Z". | ||
output: true | ||
- name: 'description' | ||
type: String | ||
description: | | ||
Description for the quota rule. | ||
- name: 'labels' | ||
type: KeyValueLabels | ||
description: | | ||
Labels as key value pairs of the quota rule. Example: `{ "owner": "Bob", "department": "finance", "purpose": "testing" }`. |
29 changes: 29 additions & 0 deletions
29
mmv1/templates/terraform/examples/netapp_volume_quota_rule_basic.tf.tmpl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
resource "google_netapp_storage_pool" "default" { | ||
name = "{{index $.Vars "pool_name"}}" | ||
location = "us-west2" | ||
service_level = "PREMIUM" | ||
capacity_gib = 2048 | ||
network = data.google_compute_network.default.id | ||
} | ||
|
||
resource "google_netapp_volume" "default" { | ||
location = google_netapp_storage_pool.default.location | ||
name = "{{index $.Vars "volume_name"}}" | ||
capacity_gib = 100 | ||
share_name = "{{index $.Vars "volume_name"}}" | ||
storage_pool = google_netapp_storage_pool.default.name | ||
protocols = ["NFSV3"] | ||
} | ||
|
||
resource "google_netapp_volume_quota_rule" "{{$.PrimaryResourceId}}" { | ||
depends_on = [google_netapp_volume.default] | ||
location = google_netapp_volume.default.location | ||
volume_name = google_netapp_volume.default.name | ||
type = "DEFAULT_USER_QUOTA" | ||
disk_limit_mib = 50 | ||
name = "{{index $.Vars "quota_rule_name"}}" | ||
} | ||
|
||
data "google_compute_network" "default" { | ||
name = "{{index $.Vars "network_name"}}" | ||
} |
127 changes: 127 additions & 0 deletions
127
mmv1/third_party/terraform/services/netapp/resource_netapp_volume_quotaRule_sweeper.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
package netapp | ||
|
||
import ( | ||
"context" | ||
"log" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-provider-google/google/envvar" | ||
"github.com/hashicorp/terraform-provider-google/google/sweeper" | ||
"github.com/hashicorp/terraform-provider-google/google/tpgresource" | ||
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" | ||
) | ||
|
||
func init() { | ||
sweeper.AddTestSweepers("NetappVolumeQuotaRule", testSweepNetappVolumeQuotaRule) | ||
} | ||
|
||
// At the time of writing, the CI only passes us-central1 as the region | ||
func testSweepNetappVolumeQuotaRule(region string) error { | ||
resourceName := "NetappVolumeQuotaRule" | ||
log.Printf("[INFO][SWEEPER_LOG] Starting sweeper for %s", resourceName) | ||
|
||
config, err := sweeper.SharedConfigForRegion(region) | ||
if err != nil { | ||
log.Printf("[INFO][SWEEPER_LOG] error getting shared config for region: %s", err) | ||
return err | ||
} | ||
|
||
err = config.LoadAndValidate(context.Background()) | ||
if err != nil { | ||
log.Printf("[INFO][SWEEPER_LOG] error loading: %s", err) | ||
return err | ||
} | ||
|
||
t := &testing.T{} | ||
billingId := envvar.GetTestBillingAccountFromEnv(t) | ||
|
||
regions := []string{"us-central1", "us-west2", "us-east4"} | ||
for _, r := range regions { | ||
log.Printf("[INFO][SWEEPER_LOG] Starting sweeper for %s in %s", resourceName, r) | ||
|
||
// Setup variables to replace in list template | ||
d := &tpgresource.ResourceDataMock{ | ||
FieldsInSchema: map[string]interface{}{ | ||
"project": config.Project, | ||
"region": r, | ||
"location": r, | ||
"zone": "-", | ||
"billing_account": billingId, | ||
}, | ||
} | ||
|
||
listTemplate := strings.Split("https://netapp.googleapis.com/v1/projects/{{project}}/locations/{{location}}/volumes/{{volume_name}}/quotaRules", "?")[0] | ||
listUrl, err := tpgresource.ReplaceVars(d, config, listTemplate) | ||
if err != nil { | ||
log.Printf("[INFO][SWEEPER_LOG] error preparing sweeper list url: %s", err) | ||
continue | ||
} | ||
|
||
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ | ||
Config: config, | ||
Method: "GET", | ||
Project: config.Project, | ||
RawURL: listUrl, | ||
UserAgent: config.UserAgent, | ||
}) | ||
if err != nil { | ||
log.Printf("[INFO][SWEEPER_LOG] Error in response from request %s: %s", listUrl, err) | ||
continue | ||
} | ||
|
||
resourceList, ok := res["volumeQuotaRules"] | ||
if !ok { | ||
log.Printf("[INFO][SWEEPER_LOG] Nothing found in response.") | ||
continue | ||
} | ||
|
||
rl := resourceList.([]interface{}) | ||
|
||
log.Printf("[INFO][SWEEPER_LOG] Found %d items in %s list response.", len(rl), resourceName) | ||
// Keep count of items that aren't sweepable for logging. | ||
nonPrefixCount := 0 | ||
for _, ri := range rl { | ||
obj := ri.(map[string]interface{}) | ||
if obj["name"] == nil { | ||
log.Printf("[INFO][SWEEPER_LOG] %s resource name was nil", resourceName) | ||
continue | ||
} | ||
|
||
name := tpgresource.GetResourceNameFromSelfLink(obj["name"].(string)) | ||
// Skip resources that shouldn't be sweeped | ||
if !sweeper.IsSweepableTestResource(name) { | ||
nonPrefixCount++ | ||
continue | ||
} | ||
|
||
deleteTemplate := "https://netapp.googleapis.com/v1/projects/{{project}}/locations/{{location}}/volumes/{{volume_name}}/quotaRules/{{name}}" | ||
deleteUrl, err := tpgresource.ReplaceVars(d, config, deleteTemplate) | ||
if err != nil { | ||
log.Printf("[INFO][SWEEPER_LOG] error preparing delete url: %s", err) | ||
continue | ||
} | ||
deleteUrl = deleteUrl + name | ||
|
||
// Don't wait on operations as we may have a lot to delete | ||
_, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ | ||
Config: config, | ||
Method: "DELETE", | ||
Project: config.Project, | ||
RawURL: deleteUrl, | ||
UserAgent: config.UserAgent, | ||
}) | ||
if err != nil { | ||
log.Printf("[INFO][SWEEPER_LOG] Error deleting for url %s : %s", deleteUrl, err) | ||
} else { | ||
log.Printf("[INFO][SWEEPER_LOG] Sent delete request for %s resource: %s", resourceName, name) | ||
} | ||
} | ||
|
||
if nonPrefixCount > 0 { | ||
log.Printf("[INFO][SWEEPER_LOG] %d items were non-sweepable and skipped.", nonPrefixCount) | ||
} | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.