Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: Add dimensions argument to consumer quota override #683

Merged
merged 17 commits into from
Apr 12, 2022

Conversation

stanley98yu
Copy link
Contributor

Fixes: #665

I was thinking about adding a test, but I don't have gsuite set up. Is there a non-gsuite-enabled test that would be best?

@stanley98yu stanley98yu requested a review from a team as a code owner February 1, 2022 14:32
Copy link
Member

@bharathkkb bharathkkb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @stanley98yu
A test would be great. I am not sure what you meant by gsuite as the example inputs only seem to require a project_id.

@stanley98yu
Copy link
Contributor Author

Sorry about the vague question--I misunderstood how the tests are setup.

I've tried adding a new test suite for quota_project, but I'm confused about how Kitchen finds the tests if we don't specify the test location. We specify the fixtures in kitchen.yml, but not the tests in test/integration/controls. Am I missing something? I've pushed my code to show what I've written out so far.

@bharathkkb
Copy link
Member

@stanley98yu np, it is linked via the test name quota_project which you also have in the inspec.yml for a given test. Since this is a new test, could you use our newer framework? We are trying to phase out the old ruby based tests. New docs are here: https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/tree/master/infra/blueprint-test
Some example repos are https://github.com/terraform-google-modules/terraform-google-network and https://github.com/terraform-google-modules/terraform-google-event-function

@stanley98yu
Copy link
Contributor Author

Hey @bharathkkb I'm having some trouble using the new test framework. How do I run an arbitrary shell command that isn't gcloud? I think in order to display quotas, I need to curl the Service Consumer Management API endpoint according to: https://cloud.google.com/service-infrastructure/docs/manage-consumer-quota.

I tried looking at https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/blob/master/infra/blueprint-test/pkg/gcloud/gcloud.go to see how the test commands work, but I'm still new to Go. I've pushed my current test setup if you want to take a look. Let me know your thoughts/alternatives

@bharathkkb
Copy link
Member

@stanley98yu I'll ping you

Comment on lines 50 to 57
gcurlCmd := shell.Command{
Command: "gcurl",
Args: []string{fmt.Sprintf("https://serviceconsumermanagement.googleapis.com/v1beta1/services/%s/projects/%s/consumerQuotaMetrics", computeAPI, projectID)},
}
op, err := shell.RunCommandAndGetStdOutE(t, gcurlCmd)
if err != nil {
t.Fatal(err)
}
Copy link
Member

@bharathkkb bharathkkb Feb 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets check if gcloud is available. If not, I am leaning towards using https://pkg.go.dev/golang.org/x/oauth2/google#DefaultClient to make the request. We can add a helper to the test framework if there is verbose logic. Based on the API doc, something like below is what I was thinking

httpClient, err := google.DefaultClient(oauth2.NoContext,
		"https://www.googleapis.com/auth/cloud-platform")
	if err != nil {
		t.Fatalf("",err)
	}
resp, err := httpClient.Get(runEndPointUrl)
	if err != nil {
		t.Fatalf("",err)
	}
	// use utils.ParseJSONResult on resp.Body 

@bharathkkb
Copy link
Member

@stanley98yu Hoping to pull this into #684 as its a breaking change if you have bandwidth. We can defer the test to a follow up PR if you can validate and add an upgrade guide.

@stanley98yu
Copy link
Contributor Author

@bharathkkb Sorry about the delay, but I don't think I can verify WAI just yet. The dimensions argument doesn't show up in terraform plan, and I'm also still having trouble with the test. I think it may be best to delay adding this feature in until I can put some time to figuring it out. Again, sorry about the inconvenience.

@bharathkkb
Copy link
Member

@stanley98yu no worries, we can hold for next release. Thanks for checking!

@stanley98yu
Copy link
Contributor Author

stanley98yu commented Mar 25, 2022

I'm able to verify that the feature is WAI but with two notes:

  • The issue before was that setting the dimensions type constraint as object({}) implies it doesn't have any attributes (and ignores additional ones). dimensions's attributes depend on the specific metric, so I don't know if there's a type constraint that isn't any to match objects with variable attribute names. Is this the correct approach?
  • I ended up not being able to find a gcloud-equivalent command for calling the Service Usage API, so I stuck with using an HTTP client to call the API.
  • The checks seem to fail for apply-essential-contacts-example, but I don't think the failures are related to my changes? Note: The test passes when I run manually and passed after re-running.

Copy link
Member

@bharathkkb bharathkkb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this! Some minor nits related to test below.

The issue before was that setting the dimensions type constraint as object({}) implies it doesn't have any attributes

Baseed on example would map(string) be a better type?

I ended up not being able to find a gcloud-equivalent command for calling the Service Usage API, so I stuck with using an HTTP client to call the API.

Sounds good, this might also be something we can add to the test framework if you are interested in opening an issue here.

The checks seem to fail for apply-essential-contacts-example

Yeah that seemed like a flake.


projectID := quotaProjectT.GetStringOutput("project_id")

apis := gcloud.Run(t, fmt.Sprintf("services list --project %s", projectID))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: newer versions of the framework has a Runf method which is a bit cleaner

Suggested change
apis := gcloud.Run(t, fmt.Sprintf("services list --project %s", projectID))
apis := gcloud.Runf(t, "services list --project %s", projectID)

Comment on lines 46 to 48
if err != nil {
t.Fatalf("%s", err)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: since we already have assert. https://pkg.go.dev/github.com/stretchr/testify/assert#NoError

Suggested change
if err != nil {
t.Fatalf("%s", err)
}
assert.NoError(err)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here and throughout

}
result = utils.ParseJSONResult(t, string(body))
assert.Equal("95", result.Get("overrides.0.overrideValue").String(), "has correct consumer quota override value")
assert.True(!result.Get("overrides.0.dimensions").Exists(), "has correct consumer quota override dimensions")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seemed a bit confusing - reworded slightly based on fixture

Suggested change
assert.True(!result.Get("overrides.0.dimensions").Exists(), "has correct consumer quota override dimensions")
assert.False(result.Get("overrides.0.dimensions").Exists(), "has empty dimensions")

if err != nil {
t.Fatalf("%s", err)
}
body, err := io.ReadAll(resp.Body)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

close body to prevent leaks

Suggested change
body, err := io.ReadAll(resp.Body)
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)

@stanley98yu
Copy link
Contributor Author

Thanks, @bharathkkb! I've updated with the suggestions.

@bharathkkb
Copy link
Member

hold for next breaking

@bharathkkb bharathkkb changed the title Add dimensions argument to consumer quota override feat!: Add dimensions argument to consumer quota override Apr 8, 2022
@comment-bot-dev
Copy link

@stanley98yu
Thanks for the PR! 🚀
✅ Lint checks have passed.

@bharathkkb bharathkkb merged commit d1d7624 into master Apr 12, 2022
@bharathkkb bharathkkb deleted the dimensions branch April 12, 2022 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

quota_manager doesn't support dimensions map argument
3 participants