-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Add support to configure the default stack used by Cloud commands #5420
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
base: master
Are you sure you want to change the base?
Conversation
cloudapi/api.go
Outdated
| // ValidateAuth validates a token and stack URL, returning the stack ID and default project ID. | ||
| // The stackURL must be a normalized full URL (e.g., https://my-team.grafana.net). | ||
| func (c *Client) ValidateAuth(stackURL string) (*AuthenticationResponse, error) { | ||
| req, err := http.NewRequest(http.MethodGet, "https://api.k6.io/cloud/v6/auth", nil) //nolint:noctx |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not blocking nor critical 👇🏻
I understand why this cannot use c.baseURL here, as the baseURL contains the v1 path. However, I would prefer for us not to hardcode the API URL here if possible.
I would suggest refactoring the client if possible to store the API version it talks to, and select the base api path to use according:
- "/v1" if talking to the v1 API
- "/cloud/v6" if talking to the v6 API
Specifically thinking of this code here:
Line 44 in cefb446
| baseURL: fmt.Sprintf("%s/v1", host), |
In an ideal world, I think this should call something along the lines of c.BaseURL(cloudAPIVersion6) and get a fully qualified url as a result 🙇🏻
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made the changes! Let me know what you think 👀
| return fmt.Errorf( | ||
| "your stack is invalid - please, consult the Grafana Cloud k6 documentation "+ | ||
| "for instructions on how to get yours: "+ | ||
| "https://grafana.com/docs/grafana-cloud/testing/k6/author-run/something-stack: %w", | ||
| err) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This URL doesn't resolve in my browser, I would suggest pointing to a URL that does exist and help the user? 🙇🏻
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sadly, I think there is no page for this at the moment. The closest is this but it doesn't really tell you anything...
Thoughts on this @heitortsergent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the information we need from the docs about how to retrieve the stack name or URL?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @dgzlopes, thanks for your contribution. 🙇
It sounds a great start, however the main missing point is the complete absence of test coverage. This is a mission critical feature, so I don't think we should release this without a good coverage.
Most of the building blocks should be already there for making this possible.
In addition, if possible, anything not strictly necessary for the stack/project ID definition should be moved out in a separated pull request to reduce the current complexity.
cloudapi/api.go
Outdated
| // ValidateAuth validates a token and stack URL, returning the stack ID and default project ID. | ||
| // The stackURL must be a normalized full URL (e.g., https://my-team.grafana.net). | ||
| func (c *Client) ValidateAuth(stackURL string) (*AuthenticationResponse, error) { | ||
| req, err := http.NewRequest(http.MethodGet, "https://api.k6.io/cloud/v6/auth", nil) //nolint:noctx |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| req, err := http.NewRequest(http.MethodGet, "https://api.k6.io/cloud/v6/auth", nil) //nolint:noctx | |
| req, err := http.NewRequestWithContext(http.MethodGet, c.authBase, nil) //nolint:noctx |
In addition, we should use the context, so we can cancel the requests when the user aborts the script.
| } | ||
|
|
||
| // AuthenticationResponse represents the response from the /cloud/v6/auth endpoint. | ||
| type AuthenticationResponse struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| type AuthenticationResponse struct { | |
| type authenticationResponse struct { |
do we really need to export it?
| err := migrateLegacyConfigFileIfAny(c.globalState) | ||
| if err != nil { | ||
| return err | ||
| if !checkIfMigrationCompleted(c.globalState) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you isolate this change in a separated pull request, please? It doesn't sound necessary to stay here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change should stay in a cloud file and not in common.go
| return cloudConfig.DefaultProjectID.Int64, nil | ||
| } | ||
| return 0, fmt.Errorf( | ||
| "default stack configured but default project ID not available - " + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| "default stack configured but default project ID not available - " + | |
| "default stack configured but the default project ID is not available - " + |
| ProjectID null.Int `json:"projectID" envconfig:"K6_CLOUD_PROJECT_ID"` | ||
| Name null.String `json:"name" envconfig:"K6_CLOUD_NAME"` | ||
| StackID null.Int `json:"stackID,omitempty" envconfig:"K6_CLOUD_STACK_ID"` | ||
| StackURL null.String `json:"stackURL,omitempty" envconfig:"K6_CLOUD_STACK"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| StackURL null.String `json:"stackURL,omitempty" envconfig:"K6_CLOUD_STACK"` | |
| StackURL null.String `json:"stackURL,omitempty" envconfig:"K6_CLOUD_STACK_URL"` |
I added URL because 2 out of 3 have it, but if the intention is to not have it then remove it from the other two.
|
|
||
| // Only merge ProjectID, Name, Token, and StackID from options. | ||
| // StackURL and DefaultProjectID can only be set via login. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we get this check in a position near to the others, please?
| consolidatedCurrentConfig, warn, err := cloudapi.GetConsolidatedConfig( | ||
| jsonRawConf, gs.Env, "", nil, nil) | ||
| if err != nil { | ||
| return "", 0, 0, err | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I expect the config to be a dependency and not a direct call here.
| // as expected by the Cloud output. | ||
| // | ||
| //nolint:funlen | ||
| //nolint:funlen,gocognit,cyclop |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a signal that we should try to do better here. I'd like to see a proposal for an improvement.
| c.gs.Events.UnsubscribeAll() | ||
| }() | ||
|
|
||
| printBanner(c.gs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we expect this
|
Also 🏓 👀 @AgnesToulet as this will be relevant to using the v6 api in k6, as it implements a requirement to be able to even interact with the api (the stack url/id we mentioned prior). |
|
|
||
| // ValidateAuth validates a token and stack URL, returning the stack ID and default project ID. | ||
| // The stackURL must be a normalized full URL (e.g., https://my-team.grafana.net). | ||
| func (c *Client) ValidateAuth(stackURL string) (*AuthenticationResponse, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use the generated go client for this operation?
https://github.com/grafana/k6-cloud-openapi-client-go/blob/main/k6/docs/AuthorizationAPI.md#auth
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have the same question actually. And more than that, should it be the goal for all v6 endpoints to be called via that library?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be great but would probably need a larger refactor, not directly related to what this PR does. I'm planning to use this library when working on #5009 and I can update this function then.
| } | ||
| }() | ||
|
|
||
| if err := CheckResponse(resp); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error schema in v6 AP is different from the old one. Should the error handling code be updated too?
| // BaseURL returns the fully qualified base URL for the specified API version. | ||
| // It returns: | ||
| // - "{client.host}/v1" for APIVersion1 | ||
| // - "https://api.k6.io/cloud/v6" for APIVersion6 | ||
| func (c *Client) BaseURL(apiVersion APIVersion) string { | ||
| switch apiVersion { | ||
| case APIVersion6: | ||
| return "https://api.k6.io/cloud/v6" | ||
| default: | ||
| return fmt.Sprintf("%s/v1", c.host) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change might break k6-operator code if PLZ endpoints (a mix of v1 and v4 at api.k6.io) are not taken into account here. They don't seem to be ATM.
|
Thanks for the ping @oleiade. I have left a couple of comments already but there is more 😂 Here are my questions / observations about this change (this is not a review as such, but more of my thinking about "how we're going to use this in the future"):
|
What?
As described in the Design Doc, this PR implements support to configure the default Grafana Cloud Stack.
Checklist
make check) and all pass.Checklist: Documentation (only for k6 maintainers and if relevant)
Please do not merge this PR until the following items are filled out.
Related PR(s)/Issue(s)
Closes #4008