pulumi/pkg/backend/httpstate/client/client.go

1297 lines
45 KiB
Go
Raw Normal View History

Add tokens.StackName (#14487) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> This adds a new type `tokens.StackName` which is a relatively strongly typed container for a stack name. The only weakly typed aspect of it is Go will always allow the "zero" value to be created for a struct, which for a stack name is the empty string which is invalid. To prevent introducing unexpected empty strings when working with stack names the `String()` method will panic for zero initialized stack names. Apart from the zero value, all other instances of `StackName` are via `ParseStackName` which returns a descriptive error if the string is not valid. This PR only updates "pkg/" to use this type. There are a number of places in "sdk/" which could do with this type as well, but there's no harm in doing a staggered roll out, and some parts of "sdk/" are user facing and will probably have to stay on the current `tokens.Name` and `tokens.QName` types. There are two places in the system where we panic on invalid stack names, both in the http backend. This _should_ be fine as we've had long standing validation that stacks created in the service are valid stack names. Just in case people have managed to introduce invalid stack names, there is the `PULUMI_DISABLE_VALIDATION` environment variable which will turn off the validation _and_ panicing for stack names. Users can use that to temporarily disable the validation and continue working, but it should only be seen as a temporary measure. If they have invalid names they should rename them, or if they think they should be valid raise an issue with us to change the validation code. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-15 07:44:54 +00:00
// Copyright 2016-2023, Pulumi Corporation.
2018-05-22 19:43:36 +00:00
//
// 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.
package client
import (
Adds Pulumi AI integrations with Pulumi New (#14685) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Now that we support .zip archive sources for Pulumi New, we have all of the API surface we need to provide a full Pulumi New experience using Pulumi AI. This PR introduces a few modes of interacting with Pulumi AI to generate Pulumi projects. - The default `pulumi new` experience now begins with a choice between `ai` and `template` modes - the `template` mode represents the current state of running `pulumi new`, while `ai` provides an interactive experience with Pulumi AI. - The user can iteratively ask questions to improve or change the resulting program - each time a prompt is completed, they are asked to `refine`, `no`, or `yes` their session - `refine` allows a follow-on prompt to be submitted. `no` ends the session without generating a pulumi project, and `yes` generates a Pulumi project from the most recent program returned by Pulumi AI. - Additionally, top-level flags, `--ai` and `--language` are provided to fill in default values for the AI mode. When a prompt is provided with a language, it is automatically submitted to Pulumi AI - if either is missing, the user is prompted for whichever value is missing. Fixes https://github.com/pulumi/pulumi.ai/issues/441 Fixes https://github.com/pulumi/pulumi.ai/issues/443 Fixes https://github.com/pulumi/pulumi.ai/issues/444 Depends on https://github.com/pulumi/pulumi.ai/pull/472 Depends on https://github.com/pulumi/pulumi.ai/pull/507 Depends on https://github.com/pulumi/pulumi.ai/pull/508 ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. --> --------- Co-authored-by: Aaron Friel <mayreply@aaronfriel.com>
2023-12-20 22:08:09 +00:00
"bytes"
"context"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
2019-07-10 17:55:42 +00:00
"io"
"net/http"
Adds two new CLI features - search and AI search (#13611) Adds initial pulumi search implementation <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/13489 Fixes https://github.com/pulumi/pulumi/issues/12868 ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-08-21 15:06:46 +00:00
"net/url"
"path"
2020-02-25 01:11:56 +00:00
"regexp"
"strconv"
"time"
"github.com/blang/semver"
"github.com/opentracing/opentracing-go"
"github.com/pulumi/pulumi/pkg/v3/engine"
"github.com/pulumi/pulumi/pkg/v3/util/validation"
"github.com/pulumi/pulumi/sdk/v3/go/common/apitype"
"github.com/pulumi/pulumi/sdk/v3/go/common/diag"
"github.com/pulumi/pulumi/sdk/v3/go/common/diag/colors"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource/config"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource/plugin"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
"github.com/pulumi/pulumi/sdk/v3/go/common/workspace"
)
// Client provides a slim wrapper around the Pulumi HTTP/REST API.
type Client struct {
apiURL string
apiToken apiAccessToken
apiUser string
apiOrgs []string
tokenInfo *workspace.TokenInformation // might be nil if running against old services
diag diag.Sink
insecure bool
restClient restClient
httpClient *http.Client
2022-11-22 16:47:45 +00:00
// If true, do not probe the backend with GET /api/capabilities and assume no capabilities.
DisableCapabilityProbing bool
}
// newClient creates a new Pulumi API client with the given URL and API token. It is a variable instead of a regular
// function so it can be set to a different implementation at runtime, if necessary.
var newClient = func(apiURL, apiToken string, insecure bool, d diag.Sink) *Client {
var httpClient *http.Client
if insecure {
tr := &http.Transport{
//nolint:gosec // The user has explicitly opted into setting this
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
httpClient = &http.Client{Transport: tr}
} else {
httpClient = http.DefaultClient
}
return &Client{
apiURL: apiURL,
apiToken: apiAccessToken(apiToken),
diag: d,
httpClient: httpClient,
restClient: &defaultRESTClient{
client: &defaultHTTPClient{
client: httpClient,
},
},
}
}
// Returns true if this client is insecure (i.e. has TLS disabled).
func (pc *Client) Insecure() bool {
return pc.insecure
}
// NewClient creates a new Pulumi API client with the given URL and API token.
func NewClient(apiURL, apiToken string, insecure bool, d diag.Sink) *Client {
return newClient(apiURL, apiToken, insecure, d)
}
// URL returns the URL of the API endpoint this client interacts with
func (pc *Client) URL() string {
return pc.apiURL
}
Adds Pulumi AI integrations with Pulumi New (#14685) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Now that we support .zip archive sources for Pulumi New, we have all of the API surface we need to provide a full Pulumi New experience using Pulumi AI. This PR introduces a few modes of interacting with Pulumi AI to generate Pulumi projects. - The default `pulumi new` experience now begins with a choice between `ai` and `template` modes - the `template` mode represents the current state of running `pulumi new`, while `ai` provides an interactive experience with Pulumi AI. - The user can iteratively ask questions to improve or change the resulting program - each time a prompt is completed, they are asked to `refine`, `no`, or `yes` their session - `refine` allows a follow-on prompt to be submitted. `no` ends the session without generating a pulumi project, and `yes` generates a Pulumi project from the most recent program returned by Pulumi AI. - Additionally, top-level flags, `--ai` and `--language` are provided to fill in default values for the AI mode. When a prompt is provided with a language, it is automatically submitted to Pulumi AI - if either is missing, the user is prompted for whichever value is missing. Fixes https://github.com/pulumi/pulumi.ai/issues/441 Fixes https://github.com/pulumi/pulumi.ai/issues/443 Fixes https://github.com/pulumi/pulumi.ai/issues/444 Depends on https://github.com/pulumi/pulumi.ai/pull/472 Depends on https://github.com/pulumi/pulumi.ai/pull/507 Depends on https://github.com/pulumi/pulumi.ai/pull/508 ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. --> --------- Co-authored-by: Aaron Friel <mayreply@aaronfriel.com>
2023-12-20 22:08:09 +00:00
// do proxies the http client's Do method. This is a low-level construct and should be used sparingly
func (pc *Client) do(ctx context.Context, req *http.Request) (*http.Response, error) {
return pc.httpClient.Do(req.WithContext(ctx))
}
// restCall makes a REST-style request to the Pulumi API using the given method, path, query object, and request
// object. If a response object is provided, the server's response is deserialized into that object.
func (pc *Client) restCall(ctx context.Context, method, path string, queryObj, reqObj, respObj interface{}) error {
return pc.restClient.Call(ctx, pc.diag, pc.apiURL, method, path, queryObj, reqObj, respObj, pc.apiToken,
httpCallOptions{})
}
// restCall makes a REST-style request to the Pulumi API using the given method, path, query object, and request
// object. If a response object is provided, the server's response is deserialized into that object.
func (pc *Client) restCallWithOptions(ctx context.Context, method, path string, queryObj, reqObj,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
respObj interface{}, opts httpCallOptions,
) error {
return pc.restClient.Call(ctx, pc.diag, pc.apiURL, method, path, queryObj, reqObj, respObj, pc.apiToken, opts)
}
// updateRESTCall makes a REST-style request to the Pulumi API using the given method, path, query object, and request
// object. The call is authorized with the indicated update token. If a response object is provided, the server's
// response is deserialized into that object.
func (pc *Client) updateRESTCall(ctx context.Context, method, path string, queryObj, reqObj, respObj interface{},
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
token updateToken, httpOptions httpCallOptions,
) error {
return pc.restClient.Call(ctx, pc.diag, pc.apiURL, method, path, queryObj, reqObj, respObj, token, httpOptions)
}
// getProjectPath returns the API path for the given owner and the given project name joined with path separators
// and appended to the stack root.
func getProjectPath(owner string, projectName string) string {
return fmt.Sprintf("/api/stacks/%s/%s", owner, projectName)
}
// getStackPath returns the API path to for the given stack with the given components joined with path separators
// and appended to the stack root.
func getStackPath(stack StackIdentifier, components ...string) string {
prefix := fmt.Sprintf("/api/stacks/%s/%s/%s", stack.Owner, stack.Project, stack.Stack)
return path.Join(append([]string{prefix}, components...)...)
}
2020-01-16 20:04:51 +00:00
// listPolicyGroupsPath returns the path for an API call to the Pulumi service to list the Policy Groups
// in a Pulumi organization.
func listPolicyGroupsPath(orgName string) string {
return fmt.Sprintf("/api/orgs/%s/policygroups", orgName)
}
// listPolicyPacksPath returns the path for an API call to the Pulumi service to list the Policy Packs
// in a Pulumi organization.
func listPolicyPacksPath(orgName string) string {
return fmt.Sprintf("/api/orgs/%s/policypacks", orgName)
}
// publishPolicyPackPath returns the path for an API call to the Pulumi service to publish a new Policy Pack
// in a Pulumi organization.
func publishPolicyPackPath(orgName string) string {
return fmt.Sprintf("/api/orgs/%s/policypacks", orgName)
}
2020-01-03 22:16:39 +00:00
// updatePolicyGroupPath returns the path for an API call to the Pulumi service to update a PolicyGroup
// for a Pulumi organization.
func updatePolicyGroupPath(orgName, policyGroup string) string {
return fmt.Sprintf(
"/api/orgs/%s/policygroups/%s", orgName, policyGroup)
}
2020-01-27 18:35:34 +00:00
// deletePolicyPackPath returns the path for an API call to the Pulumi service to delete
// all versions of a Policy Pack from a Pulumi organization.
func deletePolicyPackPath(orgName, policyPackName string) string {
return fmt.Sprintf("/api/orgs/%s/policypacks/%s", orgName, policyPackName)
}
2020-01-03 22:16:39 +00:00
// deletePolicyPackVersionPath returns the path for an API call to the Pulumi service to delete
2020-01-27 18:35:34 +00:00
// a version of a Policy Pack from a Pulumi organization.
2020-02-25 01:11:56 +00:00
func deletePolicyPackVersionPath(orgName, policyPackName, versionTag string) string {
2020-01-03 22:16:39 +00:00
return fmt.Sprintf(
2020-02-25 01:11:56 +00:00
"/api/orgs/%s/policypacks/%s/versions/%s", orgName, policyPackName, versionTag)
2020-01-03 22:16:39 +00:00
}
// publishPolicyPackPublishComplete returns the path for an API call to signal to the Pulumi service
// that a PolicyPack to a Pulumi organization.
2020-02-25 01:11:56 +00:00
func publishPolicyPackPublishComplete(orgName, policyPackName string, versionTag string) string {
return fmt.Sprintf(
2020-02-25 01:11:56 +00:00
"/api/orgs/%s/policypacks/%s/versions/%s/complete", orgName, policyPackName, versionTag)
}
// getPolicyPackConfigSchemaPath returns the API path to retrieve the policy pack configuration schema.
func getPolicyPackConfigSchemaPath(orgName, policyPackName string, versionTag string) string {
return fmt.Sprintf(
"/api/orgs/%s/policypacks/%s/versions/%s/schema", orgName, policyPackName, versionTag)
}
Adds Pulumi AI integrations with Pulumi New (#14685) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Now that we support .zip archive sources for Pulumi New, we have all of the API surface we need to provide a full Pulumi New experience using Pulumi AI. This PR introduces a few modes of interacting with Pulumi AI to generate Pulumi projects. - The default `pulumi new` experience now begins with a choice between `ai` and `template` modes - the `template` mode represents the current state of running `pulumi new`, while `ai` provides an interactive experience with Pulumi AI. - The user can iteratively ask questions to improve or change the resulting program - each time a prompt is completed, they are asked to `refine`, `no`, or `yes` their session - `refine` allows a follow-on prompt to be submitted. `no` ends the session without generating a pulumi project, and `yes` generates a Pulumi project from the most recent program returned by Pulumi AI. - Additionally, top-level flags, `--ai` and `--language` are provided to fill in default values for the AI mode. When a prompt is provided with a language, it is automatically submitted to Pulumi AI - if either is missing, the user is prompted for whichever value is missing. Fixes https://github.com/pulumi/pulumi.ai/issues/441 Fixes https://github.com/pulumi/pulumi.ai/issues/443 Fixes https://github.com/pulumi/pulumi.ai/issues/444 Depends on https://github.com/pulumi/pulumi.ai/pull/472 Depends on https://github.com/pulumi/pulumi.ai/pull/507 Depends on https://github.com/pulumi/pulumi.ai/pull/508 ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. --> --------- Co-authored-by: Aaron Friel <mayreply@aaronfriel.com>
2023-12-20 22:08:09 +00:00
// getAIPromptPath returns the API path to create a Pulumi AI prompt.
func getAIPromptPath() string {
return "/api/ai/template"
}
// getUpdatePath returns the API path to for the given stack with the given components joined with path separators
// and appended to the update root.
func getUpdatePath(update UpdateIdentifier, components ...string) string {
components = append([]string{string(apitype.UpdateUpdate), update.UpdateID}, components...)
return getStackPath(update.StackIdentifier, components...)
}
// Copied from https://github.com/pulumi/pulumi-service/blob/master/pkg/apitype/users.go#L7-L16
type serviceUserInfo struct {
Name string `json:"name"`
GitHubLogin string `json:"githubLogin"`
AvatarURL string `json:"avatarUrl"`
Email string `json:"email,omitempty"`
}
// Copied from https://github.com/pulumi/pulumi-service/blob/master/pkg/apitype/users.go#L20-L37
type serviceUser struct {
ID string `json:"id"`
GitHubLogin string `json:"githubLogin"`
Name string `json:"name"`
Email string `json:"email"`
AvatarURL string `json:"avatarUrl"`
Organizations []serviceUserInfo `json:"organizations"`
Identities []string `json:"identities"`
SiteAdmin *bool `json:"siteAdmin,omitempty"`
TokenInfo *serviceTokenInfo `json:"tokenInfo,omitempty"`
}
// Copied from https://github.com/pulumi/pulumi-service/blob/master/pkg/apitype/users.go#L39-L43
type serviceTokenInfo struct {
Name string `json:"name"`
Organization string `json:"organization,omitempty"`
Team string `json:"team,omitempty"`
}
// GetPulumiAccountDetails returns the user implied by the API token associated with this client.
func (pc *Client) GetPulumiAccountDetails(ctx context.Context) (string, []string, *workspace.TokenInformation, error) {
if pc.apiUser == "" {
resp := serviceUser{}
if err := pc.restCall(ctx, "GET", "/api/user", nil, nil, &resp); err != nil {
return "", nil, nil, err
}
2018-04-18 18:25:16 +00:00
if resp.GitHubLogin == "" {
return "", nil, nil, errors.New("unexpected response from server")
2018-04-18 18:25:16 +00:00
}
pc.apiUser = resp.GitHubLogin
pc.apiOrgs = make([]string, len(resp.Organizations))
for i, org := range resp.Organizations {
if org.GitHubLogin == "" {
return "", nil, nil, errors.New("unexpected response from server")
}
pc.apiOrgs[i] = org.GitHubLogin
}
if resp.TokenInfo != nil {
pc.tokenInfo = &workspace.TokenInformation{
Name: resp.TokenInfo.Name,
Organization: resp.TokenInfo.Organization,
Team: resp.TokenInfo.Team,
}
}
}
return pc.apiUser, pc.apiOrgs, pc.tokenInfo, nil
}
// GetCLIVersionInfo asks the service for information about versions of the CLI (the newest version as well as the
2023-12-22 16:40:12 +00:00
// oldest version before the CLI should warn about an upgrade, and the current dev version).
func (pc *Client) GetCLIVersionInfo(ctx context.Context) (semver.Version, semver.Version, semver.Version, error) {
var versionInfo apitype.CLIVersionResponse
err := pc.restCallWithOptions(
ctx,
"GET",
"/api/cli/version",
nil, // query
nil, // request
&versionInfo, // response
httpCallOptions{
RetryPolicy: retryNone,
},
)
if err != nil {
2023-12-22 16:40:12 +00:00
return semver.Version{}, semver.Version{}, semver.Version{}, err
}
latestSem, err := semver.ParseTolerant(versionInfo.LatestVersion)
if err != nil {
2023-12-22 16:40:12 +00:00
return semver.Version{}, semver.Version{}, semver.Version{}, err
}
oldestSem, err := semver.ParseTolerant(versionInfo.OldestWithoutWarning)
if err != nil {
2023-12-22 16:40:12 +00:00
return semver.Version{}, semver.Version{}, semver.Version{}, err
}
2023-12-22 16:40:12 +00:00
// If there is no dev version, return the latest and oldest
// versions. This can happen if the server does not include
// https://github.com/pulumi/pulumi-service/pull/17429 yet
if versionInfo.LatestDevVersion == "" {
return latestSem, oldestSem, semver.Version{}, nil
}
devSem, err := semver.ParseTolerant(versionInfo.LatestDevVersion)
if err != nil {
return semver.Version{}, semver.Version{}, semver.Version{}, err
}
return latestSem, oldestSem, devSem, nil
}
// ListStacksFilter describes optional filters when listing stacks.
type ListStacksFilter struct {
Project *string
Organization *string
TagName *string
TagValue *string
}
// ListStacks lists all stacks the current user has access to, optionally filtered by project.
func (pc *Client) ListStacks(
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
ctx context.Context, filter ListStacksFilter, inContToken *string,
) ([]apitype.StackSummary, *string, error) {
queryFilter := struct {
Project *string `url:"project,omitempty"`
Organization *string `url:"organization,omitempty"`
TagName *string `url:"tagName,omitempty"`
TagValue *string `url:"tagValue,omitempty"`
ContinuationToken *string `url:"continuationToken,omitempty"`
}{
Project: filter.Project,
Organization: filter.Organization,
TagName: filter.TagName,
TagValue: filter.TagValue,
ContinuationToken: inContToken,
}
var resp apitype.ListStacksResponse
if err := pc.restCall(ctx, "GET", "/api/user/stacks", queryFilter, nil, &resp); err != nil {
return nil, nil, err
}
return resp.Stacks, resp.ContinuationToken, nil
}
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
// ErrNoPreviousDeployment is returned when there isn't a previous deployment.
var ErrNoPreviousDeployment = errors.New("no previous deployment")
type getLatestConfigurationResponse struct {
Info apitype.UpdateInfo `json:"info,omitempty"`
}
// GetLatestConfiguration returns the configuration for the latest deployment of a given stack.
func (pc *Client) GetLatestConfiguration(ctx context.Context, stackID StackIdentifier) (config.Map, error) {
latest := getLatestConfigurationResponse{}
if err := pc.restCall(ctx, "GET", getStackPath(stackID, "updates", "latest"), nil, nil, &latest); err != nil {
if restErr, ok := err.(*apitype.ErrorResponse); ok {
if restErr.Code == http.StatusNotFound {
return nil, ErrNoPreviousDeployment
}
}
return nil, err
}
cfg := make(config.Map)
for k, v := range latest.Info.Config {
newKey, err := config.ParseKey(k)
if err != nil {
return nil, err
}
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
if v.Object {
if v.Secret {
cfg[newKey] = config.NewSecureObjectValue(v.String)
} else {
cfg[newKey] = config.NewObjectValue(v.String)
}
} else {
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
if v.Secret {
cfg[newKey] = config.NewSecureValue(v.String)
} else {
cfg[newKey] = config.NewValue(v.String)
}
}
}
return cfg, nil
}
// DoesProjectExist returns true if a project with the given name exists, or false otherwise.
func (pc *Client) DoesProjectExist(ctx context.Context, owner string, projectName string) (bool, error) {
if err := pc.restCall(ctx, "HEAD", getProjectPath(owner, projectName), nil, nil, nil); err != nil {
// If this was a 404, return false - project not found.
2022-11-21 16:26:09 +00:00
if is404(err) {
return false, nil
}
return false, err
}
return true, nil
}
// GetStack retrieves the stack with the given name.
func (pc *Client) GetStack(ctx context.Context, stackID StackIdentifier) (apitype.Stack, error) {
var stack apitype.Stack
if err := pc.restCall(ctx, "GET", getStackPath(stackID), nil, nil, &stack); err != nil {
return apitype.Stack{}, err
}
return stack, nil
}
// CreateStack creates a stack with the given cloud and stack name in the scope of the indicated project.
func (pc *Client) CreateStack(
ctx context.Context, stackID StackIdentifier, tags map[apitype.StackTagName]string, teams []string,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
) (apitype.Stack, error) {
// Validate names and tags.
Add tokens.StackName (#14487) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> This adds a new type `tokens.StackName` which is a relatively strongly typed container for a stack name. The only weakly typed aspect of it is Go will always allow the "zero" value to be created for a struct, which for a stack name is the empty string which is invalid. To prevent introducing unexpected empty strings when working with stack names the `String()` method will panic for zero initialized stack names. Apart from the zero value, all other instances of `StackName` are via `ParseStackName` which returns a descriptive error if the string is not valid. This PR only updates "pkg/" to use this type. There are a number of places in "sdk/" which could do with this type as well, but there's no harm in doing a staggered roll out, and some parts of "sdk/" are user facing and will probably have to stay on the current `tokens.Name` and `tokens.QName` types. There are two places in the system where we panic on invalid stack names, both in the http backend. This _should_ be fine as we've had long standing validation that stacks created in the service are valid stack names. Just in case people have managed to introduce invalid stack names, there is the `PULUMI_DISABLE_VALIDATION` environment variable which will turn off the validation _and_ panicing for stack names. Users can use that to temporarily disable the validation and continue working, but it should only be seen as a temporary measure. If they have invalid names they should rename them, or if they think they should be valid raise an issue with us to change the validation code. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-15 07:44:54 +00:00
if err := validation.ValidateStackTags(tags); err != nil {
return apitype.Stack{}, fmt.Errorf("validating stack properties: %w", err)
}
stack := apitype.Stack{
Add tokens.StackName (#14487) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> This adds a new type `tokens.StackName` which is a relatively strongly typed container for a stack name. The only weakly typed aspect of it is Go will always allow the "zero" value to be created for a struct, which for a stack name is the empty string which is invalid. To prevent introducing unexpected empty strings when working with stack names the `String()` method will panic for zero initialized stack names. Apart from the zero value, all other instances of `StackName` are via `ParseStackName` which returns a descriptive error if the string is not valid. This PR only updates "pkg/" to use this type. There are a number of places in "sdk/" which could do with this type as well, but there's no harm in doing a staggered roll out, and some parts of "sdk/" are user facing and will probably have to stay on the current `tokens.Name` and `tokens.QName` types. There are two places in the system where we panic on invalid stack names, both in the http backend. This _should_ be fine as we've had long standing validation that stacks created in the service are valid stack names. Just in case people have managed to introduce invalid stack names, there is the `PULUMI_DISABLE_VALIDATION` environment variable which will turn off the validation _and_ panicing for stack names. Users can use that to temporarily disable the validation and continue working, but it should only be seen as a temporary measure. If they have invalid names they should rename them, or if they think they should be valid raise an issue with us to change the validation code. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-15 07:44:54 +00:00
StackName: stackID.Stack.Q(),
ProjectName: stackID.Project,
OrgName: stackID.Owner,
Tags: tags,
}
createStackReq := apitype.CreateStackRequest{
Add tokens.StackName (#14487) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> This adds a new type `tokens.StackName` which is a relatively strongly typed container for a stack name. The only weakly typed aspect of it is Go will always allow the "zero" value to be created for a struct, which for a stack name is the empty string which is invalid. To prevent introducing unexpected empty strings when working with stack names the `String()` method will panic for zero initialized stack names. Apart from the zero value, all other instances of `StackName` are via `ParseStackName` which returns a descriptive error if the string is not valid. This PR only updates "pkg/" to use this type. There are a number of places in "sdk/" which could do with this type as well, but there's no harm in doing a staggered roll out, and some parts of "sdk/" are user facing and will probably have to stay on the current `tokens.Name` and `tokens.QName` types. There are two places in the system where we panic on invalid stack names, both in the http backend. This _should_ be fine as we've had long standing validation that stacks created in the service are valid stack names. Just in case people have managed to introduce invalid stack names, there is the `PULUMI_DISABLE_VALIDATION` environment variable which will turn off the validation _and_ panicing for stack names. Users can use that to temporarily disable the validation and continue working, but it should only be seen as a temporary measure. If they have invalid names they should rename them, or if they think they should be valid raise an issue with us to change the validation code. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-15 07:44:54 +00:00
StackName: stackID.Stack.String(),
Tags: tags,
Teams: teams,
}
endpoint := fmt.Sprintf("/api/stacks/%s/%s", stackID.Owner, stackID.Project)
if err := pc.restCall(
ctx, "POST", endpoint, nil, &createStackReq, nil); err != nil {
return apitype.Stack{}, err
}
return stack, nil
}
// DeleteStack deletes the indicated stack. If force is true, the stack is deleted even if it contains resources.
func (pc *Client) DeleteStack(ctx context.Context, stack StackIdentifier, force bool) (bool, error) {
path := getStackPath(stack)
queryObj := struct {
Force bool `url:"force"`
}{
Force: force,
}
err := pc.restCall(ctx, "DELETE", path, queryObj, nil, nil)
return isStackHasResourcesError(err), err
}
func isStackHasResourcesError(err error) bool {
if err == nil {
return false
}
errRsp, ok := err.(*apitype.ErrorResponse)
if !ok {
return false
}
return errRsp.Code == 400 && errRsp.Message == "Bad Request: Stack still contains resources."
}
// EncryptValue encrypts a plaintext value in the context of the indicated stack.
func (pc *Client) EncryptValue(ctx context.Context, stack StackIdentifier, plaintext []byte) ([]byte, error) {
req := apitype.EncryptValueRequest{Plaintext: plaintext}
var resp apitype.EncryptValueResponse
if err := pc.restCallWithOptions(
ctx, "POST", getStackPath(stack, "encrypt"), nil, &req, &resp,
httpCallOptions{RetryPolicy: retryAllMethods},
); err != nil {
return nil, err
}
return resp.Ciphertext, nil
}
// DecryptValue decrypts a ciphertext value in the context of the indicated stack.
func (pc *Client) DecryptValue(ctx context.Context, stack StackIdentifier, ciphertext []byte) ([]byte, error) {
req := apitype.DecryptValueRequest{Ciphertext: ciphertext}
var resp apitype.DecryptValueResponse
if err := pc.restCallWithOptions(
ctx, "POST", getStackPath(stack, "decrypt"), nil, &req, &resp,
httpCallOptions{RetryPolicy: retryAllMethods},
); err != nil {
return nil, err
}
return resp.Plaintext, nil
}
func (pc *Client) Log3rdPartySecretsProviderDecryptionEvent(ctx context.Context, stack StackIdentifier,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
secretName string,
) error {
req := apitype.Log3rdPartyDecryptionEvent{SecretName: secretName}
all: Fix revive issues Fixes the following issues found by revive included in the latest release of golangci-lint. Full list of issues: **pkg** ``` backend/display/object_diff.go:47:10: superfluous-else: if block ends with a break statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary) (revive) backend/display/object_diff.go:716:12: redefines-builtin-id: redefinition of the built-in function delete (revive) backend/display/object_diff.go:742:14: redefines-builtin-id: redefinition of the built-in function delete (revive) backend/display/object_diff.go:983:10: superfluous-else: if block ends with a continue statement, so drop this else and outdent its block (revive) backend/httpstate/backend.go:1814:4: redefines-builtin-id: redefinition of the built-in function cap (revive) backend/httpstate/backend.go:1824:5: redefines-builtin-id: redefinition of the built-in function cap (revive) backend/httpstate/client/client.go:444:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) backend/httpstate/client/client.go:455:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) cmd/pulumi/org.go:113:4: if-return: redundant if ...; err != nil check, just return error instead. (revive) cmd/pulumi/util.go:216:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) codegen/docs/gen.go:428:2: redefines-builtin-id: redefinition of the built-in function copy (revive) codegen/hcl2/model/expression.go:2151:5: redefines-builtin-id: redefinition of the built-in function close (revive) codegen/hcl2/syntax/comments.go:151:2: redefines-builtin-id: redefinition of the built-in function close (revive) codegen/hcl2/syntax/comments.go:329:3: redefines-builtin-id: redefinition of the built-in function close (revive) codegen/hcl2/syntax/comments.go:381:5: redefines-builtin-id: redefinition of the built-in function close (revive) codegen/nodejs/gen.go:1367:5: redefines-builtin-id: redefinition of the built-in function copy (revive) codegen/python/gen_program_expressions.go:136:2: redefines-builtin-id: redefinition of the built-in function close (revive) codegen/python/gen_program_expressions.go:142:3: redefines-builtin-id: redefinition of the built-in function close (revive) codegen/report/report.go:126:6: redefines-builtin-id: redefinition of the built-in function panic (revive) codegen/schema/docs_test.go:210:10: superfluous-else: if block ends with a continue statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary) (revive) codegen/schema/schema.go:790:2: redefines-builtin-id: redefinition of the built-in type any (revive) codegen/schema/schema.go:793:4: redefines-builtin-id: redefinition of the built-in type any (revive) resource/deploy/plan.go:506:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) resource/deploy/snapshot_test.go:59:3: redefines-builtin-id: redefinition of the built-in function copy (revive) resource/deploy/state_builder.go:108:2: redefines-builtin-id: redefinition of the built-in function copy (revive) ``` **sdk** ``` go/common/resource/plugin/context.go:142:2: redefines-builtin-id: redefinition of the built-in function copy (revive) go/common/resource/plugin/plugin.go:142:12: superfluous-else: if block ends with a break statement, so drop this else and outdent its block (revive) go/common/resource/properties_diff.go:114:2: redefines-builtin-id: redefinition of the built-in function len (revive) go/common/resource/properties_diff.go:117:4: redefines-builtin-id: redefinition of the built-in function len (revive) go/common/resource/properties_diff.go:122:4: redefines-builtin-id: redefinition of the built-in function len (revive) go/common/resource/properties_diff.go:127:4: redefines-builtin-id: redefinition of the built-in function len (revive) go/common/resource/properties_diff.go:132:4: redefines-builtin-id: redefinition of the built-in function len (revive) go/common/util/deepcopy/copy.go:30:1: redefines-builtin-id: redefinition of the built-in function copy (revive) go/common/workspace/creds.go:242:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) go/pulumi-language-go/main.go:569:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) go/pulumi-language-go/main.go:706:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) go/pulumi/run_test.go:925:2: redefines-builtin-id: redefinition of the built-in type any (revive) go/pulumi/run_test.go:933:3: redefines-builtin-id: redefinition of the built-in type any (revive) nodejs/cmd/pulumi-language-nodejs/main.go:778:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) python/cmd/pulumi-language-python/main.go:1011:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) python/cmd/pulumi-language-python/main.go:863:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) python/python.go:230:2: redefines-builtin-id: redefinition of the built-in function print (revive) ``` **tests** ``` integration/integration_util_test.go:282:11: superfluous-else: if block ends with a continue statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary) (revive) ```
2023-03-20 23:48:02 +00:00
return pc.restCall(
ctx, "POST", path.Join(getStackPath(stack, "decrypt"), "log-decryption"),
nil, &req, nil)
}
func (pc *Client) LogBulk3rdPartySecretsProviderDecryptionEvent(ctx context.Context, stack StackIdentifier,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
command string,
) error {
req := apitype.Log3rdPartyDecryptionEvent{CommandName: command}
all: Fix revive issues Fixes the following issues found by revive included in the latest release of golangci-lint. Full list of issues: **pkg** ``` backend/display/object_diff.go:47:10: superfluous-else: if block ends with a break statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary) (revive) backend/display/object_diff.go:716:12: redefines-builtin-id: redefinition of the built-in function delete (revive) backend/display/object_diff.go:742:14: redefines-builtin-id: redefinition of the built-in function delete (revive) backend/display/object_diff.go:983:10: superfluous-else: if block ends with a continue statement, so drop this else and outdent its block (revive) backend/httpstate/backend.go:1814:4: redefines-builtin-id: redefinition of the built-in function cap (revive) backend/httpstate/backend.go:1824:5: redefines-builtin-id: redefinition of the built-in function cap (revive) backend/httpstate/client/client.go:444:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) backend/httpstate/client/client.go:455:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) cmd/pulumi/org.go:113:4: if-return: redundant if ...; err != nil check, just return error instead. (revive) cmd/pulumi/util.go:216:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) codegen/docs/gen.go:428:2: redefines-builtin-id: redefinition of the built-in function copy (revive) codegen/hcl2/model/expression.go:2151:5: redefines-builtin-id: redefinition of the built-in function close (revive) codegen/hcl2/syntax/comments.go:151:2: redefines-builtin-id: redefinition of the built-in function close (revive) codegen/hcl2/syntax/comments.go:329:3: redefines-builtin-id: redefinition of the built-in function close (revive) codegen/hcl2/syntax/comments.go:381:5: redefines-builtin-id: redefinition of the built-in function close (revive) codegen/nodejs/gen.go:1367:5: redefines-builtin-id: redefinition of the built-in function copy (revive) codegen/python/gen_program_expressions.go:136:2: redefines-builtin-id: redefinition of the built-in function close (revive) codegen/python/gen_program_expressions.go:142:3: redefines-builtin-id: redefinition of the built-in function close (revive) codegen/report/report.go:126:6: redefines-builtin-id: redefinition of the built-in function panic (revive) codegen/schema/docs_test.go:210:10: superfluous-else: if block ends with a continue statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary) (revive) codegen/schema/schema.go:790:2: redefines-builtin-id: redefinition of the built-in type any (revive) codegen/schema/schema.go:793:4: redefines-builtin-id: redefinition of the built-in type any (revive) resource/deploy/plan.go:506:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) resource/deploy/snapshot_test.go:59:3: redefines-builtin-id: redefinition of the built-in function copy (revive) resource/deploy/state_builder.go:108:2: redefines-builtin-id: redefinition of the built-in function copy (revive) ``` **sdk** ``` go/common/resource/plugin/context.go:142:2: redefines-builtin-id: redefinition of the built-in function copy (revive) go/common/resource/plugin/plugin.go:142:12: superfluous-else: if block ends with a break statement, so drop this else and outdent its block (revive) go/common/resource/properties_diff.go:114:2: redefines-builtin-id: redefinition of the built-in function len (revive) go/common/resource/properties_diff.go:117:4: redefines-builtin-id: redefinition of the built-in function len (revive) go/common/resource/properties_diff.go:122:4: redefines-builtin-id: redefinition of the built-in function len (revive) go/common/resource/properties_diff.go:127:4: redefines-builtin-id: redefinition of the built-in function len (revive) go/common/resource/properties_diff.go:132:4: redefines-builtin-id: redefinition of the built-in function len (revive) go/common/util/deepcopy/copy.go:30:1: redefines-builtin-id: redefinition of the built-in function copy (revive) go/common/workspace/creds.go:242:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) go/pulumi-language-go/main.go:569:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) go/pulumi-language-go/main.go:706:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) go/pulumi/run_test.go:925:2: redefines-builtin-id: redefinition of the built-in type any (revive) go/pulumi/run_test.go:933:3: redefines-builtin-id: redefinition of the built-in type any (revive) nodejs/cmd/pulumi-language-nodejs/main.go:778:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) python/cmd/pulumi-language-python/main.go:1011:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) python/cmd/pulumi-language-python/main.go:863:2: if-return: redundant if ...; err != nil check, just return error instead. (revive) python/python.go:230:2: redefines-builtin-id: redefinition of the built-in function print (revive) ``` **tests** ``` integration/integration_util_test.go:282:11: superfluous-else: if block ends with a continue statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary) (revive) ```
2023-03-20 23:48:02 +00:00
return pc.restCall(
ctx, "POST", path.Join(getStackPath(stack, "decrypt"), "log-batch-decryption"),
nil, &req, nil)
}
// BulkDecryptValue decrypts a ciphertext value in the context of the indicated stack.
func (pc *Client) BulkDecryptValue(ctx context.Context, stack StackIdentifier,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
ciphertexts [][]byte,
) (map[string][]byte, error) {
req := apitype.BulkDecryptValueRequest{Ciphertexts: ciphertexts}
var resp apitype.BulkDecryptValueResponse
if err := pc.restCallWithOptions(ctx, "POST", getStackPath(stack, "batch-decrypt"), nil, &req, &resp,
httpCallOptions{GzipCompress: true, RetryPolicy: retryAllMethods}); err != nil {
return nil, err
}
return resp.Plaintexts, nil
}
// GetStackUpdates returns all updates to the indicated stack.
2021-02-08 21:13:55 +00:00
func (pc *Client) GetStackUpdates(
ctx context.Context,
stack StackIdentifier,
pageSize int,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
page int,
) ([]apitype.UpdateInfo, error) {
var response apitype.GetHistoryResponse
path := getStackPath(stack, "updates")
if pageSize > 0 {
if page < 1 {
page = 1
}
path += fmt.Sprintf("?pageSize=%d&page=%d", pageSize, page)
}
if err := pc.restCall(ctx, "GET", path, nil, nil, &response); err != nil {
return nil, err
}
return response.Updates, nil
}
// ExportStackDeployment exports the indicated stack's deployment as a raw JSON message.
// If version is nil, will export the latest version of the stack.
func (pc *Client) ExportStackDeployment(
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
ctx context.Context, stack StackIdentifier, version *int,
) (apitype.UntypedDeployment, error) {
tracingSpan, childCtx := opentracing.StartSpanFromContext(ctx, "ExportStackDeployment")
defer tracingSpan.Finish()
path := getStackPath(stack, "export")
// Tack on a specific version as desired.
if version != nil {
path += fmt.Sprintf("/%d", *version)
}
var resp apitype.ExportStackResponse
if err := pc.restCall(childCtx, "GET", path, nil, nil, &resp); err != nil {
return apitype.UntypedDeployment{}, err
}
return apitype.UntypedDeployment(resp), nil
}
// ImportStackDeployment imports a new deployment into the indicated stack.
func (pc *Client) ImportStackDeployment(ctx context.Context, stack StackIdentifier,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
deployment *apitype.UntypedDeployment,
) (UpdateIdentifier, error) {
var resp apitype.ImportStackResponse
if err := pc.restCallWithOptions(ctx, "POST", getStackPath(stack, "import"), nil, deployment, &resp,
httpCallOptions{GzipCompress: true}); err != nil {
return UpdateIdentifier{}, err
}
return UpdateIdentifier{
StackIdentifier: stack,
UpdateKind: apitype.UpdateUpdate,
UpdateID: resp.UpdateID,
}, nil
}
type CreateUpdateDetails struct {
Messages []apitype.Message
RequiredPolicies []apitype.RequiredPolicy
}
// CreateUpdate creates a new update for the indicated stack with the given kind and assorted options. If the update
// requires that the Pulumi program is uploaded, the provided getContents callback will be invoked to fetch the
// contents of the Pulumi program.
func (pc *Client) CreateUpdate(
ctx context.Context, kind apitype.UpdateKind, stack StackIdentifier, proj *workspace.Project,
cfg config.Map, m apitype.UpdateMetadata, opts engine.UpdateOptions,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
dryRun bool,
) (UpdateIdentifier, CreateUpdateDetails, error) {
// First create the update program request.
wireConfig := make(map[string]apitype.ConfigValue)
for k, cv := range cfg {
v, err := cv.Value(config.NopDecrypter)
contract.AssertNoErrorf(err, "error fetching config value for key %v", k)
wireConfig[k.String()] = apitype.ConfigValue{
String: v,
Secret: cv.Secure(),
Support lists and maps in config (#3342) This change adds support for lists and maps in config. We now allow lists/maps (and nested structures) in `Pulumi.<stack>.yaml` (or `Pulumi.<stack>.json`; yes, we currently support that). For example: ```yaml config: proj:blah: - a - b - c proj:hello: world proj:outer: inner: value proj:servers: - port: 80 ``` While such structures could be specified in the `.yaml` file manually, we support setting values in maps/lists from the command line. As always, you can specify single values with: ```shell $ pulumi config set hello world ``` Which results in the following YAML: ```yaml proj:hello world ``` And single value secrets via: ```shell $ pulumi config set --secret token shhh ``` Which results in the following YAML: ```yaml proj:token: secure: v1:VZAhuroR69FkEPTk:isKafsoZVMWA9pQayGzbWNynww== ``` Values in a list can be set from the command line using the new `--path` flag, which indicates the config key contains a path to a property in a map or list: ```shell $ pulumi config set --path names[0] a $ pulumi config set --path names[1] b $ pulumi config set --path names[2] c ``` Which results in: ```yaml proj:names - a - b - c ``` Values can be obtained similarly: ```shell $ pulumi config get --path names[1] b ``` Or setting values in a map: ```shell $ pulumi config set --path outer.inner value ``` Which results in: ```yaml proj:outer: inner: value ``` Of course, setting values in nested structures is supported: ```shell $ pulumi config set --path servers[0].port 80 ``` Which results in: ```yaml proj:servers: - port: 80 ``` If you want to include a period in the name of a property, it can be specified as: ``` $ pulumi config set --path 'nested["foo.bar"]' baz ``` Which results in: ```yaml proj:nested: foo.bar: baz ``` Examples of valid paths: - root - root.nested - 'root["nested"]' - root.double.nest - 'root["double"].nest' - 'root["double"]["nest"]' - root.array[0] - root.array[100] - root.array[0].nested - root.array[0][1].nested - root.nested.array[0].double[1] - 'root["key with \"escaped\" quotes"]' - 'root["key with a ."]' - '["root key with \"escaped\" quotes"].nested' - '["root key with a ."][100]' Note: paths that contain quotes can be surrounded by single quotes. When setting values with `--path`, if the value is `"false"` or `"true"`, it will be saved as the boolean value, and if it is convertible to an integer, it will be saved as an integer. Secure values are supported in lists/maps as well: ```shell $ pulumi config set --path --secret tokens[0] shh ``` Will result in: ```yaml proj:tokens: - secure: v1:wpZRCe36sFg1RxwG:WzPeQrCn4n+m4Ks8ps15MxvFXg== ``` Note: maps of length 1 with a key of “secure” and string value are reserved for storing secret values. Attempting to create such a value manually will result in an error: ```shell $ pulumi config set --path parent.secure foo error: "secure" key in maps of length 1 are reserved ``` **Accessing config values from the command line with JSON** ```shell $ pulumi config --json ``` Will output: ```json { "proj:hello": { "value": "world", "secret": false, "object": false }, "proj:names": { "value": "[\"a\",\"b\",\"c\"]", "secret": false, "object": true, "objectValue": [ "a", "b", "c" ] }, "proj:nested": { "value": "{\"foo.bar\":\"baz\"}", "secret": false, "object": true, "objectValue": { "foo.bar": "baz" } }, "proj:outer": { "value": "{\"inner\":\"value\"}", "secret": false, "object": true, "objectValue": { "inner": "value" } }, "proj:servers": { "value": "[{\"port\":80}]", "secret": false, "object": true, "objectValue": [ { "port": 80 } ] }, "proj:token": { "secret": true, "object": false }, "proj:tokens": { "secret": true, "object": true } } ``` If the value is a map or list, `"object"` will be `true`. `"value"` will contain the object as serialized JSON and a new `"objectValue"` property will be available containing the value of the object. If the object contains any secret values, `"secret"` will be `true`, and just like with scalar values, the value will not be outputted unless `--show-secrets` is specified. **Accessing config values from Pulumi programs** Map/list values are available to Pulumi programs as serialized JSON, so the existing `getObject`/`requireObject`/`getSecretObject`/`requireSecretObject` functions can be used to retrieve such values, e.g.: ```typescript import * as pulumi from "@pulumi/pulumi"; interface Server { port: number; } const config = new pulumi.Config(); const names = config.requireObject<string[]>("names"); for (const n of names) { console.log(n); } const servers = config.requireObject<Server[]>("servers"); for (const s of servers) { console.log(s.port); } ```
2019-11-01 20:41:27 +00:00
Object: cv.Object(),
}
}
description := ""
if proj.Description != nil {
description = *proj.Description
}
updateRequest := apitype.UpdateProgramRequest{
Name: string(proj.Name),
Runtime: proj.Runtime.Name(),
Main: proj.Main,
Description: description,
Config: wireConfig,
Options: apitype.UpdateOptions{
LocalPolicyPackPaths: engine.ConvertLocalPolicyPacksToPaths(opts.LocalPolicyPacks),
Color: colors.Raw, // force raw colorization, we handle colorization in the CLI
DryRun: dryRun,
Parallel: opts.Parallel,
ShowConfig: false, // This is a legacy option now, the engine will always emit config information
ShowReplacementSteps: false, // This is a legacy option now, the engine will always emit this information
ShowSames: false, // This is a legacy option now, the engine will always emit this information
},
Metadata: m,
}
// Create the initial update object.
var endpoint string
switch kind {
case apitype.UpdateUpdate, apitype.ResourceImportUpdate:
2018-08-03 03:13:12 +00:00
endpoint = "update"
case apitype.PreviewUpdate:
endpoint = "preview"
case apitype.RefreshUpdate:
endpoint = "refresh"
case apitype.DestroyUpdate:
endpoint = "destroy"
Replace a type used by the service (#15216) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> A type that is used by the Pulumi Cloud code was removed in [#15028](https://github.com/pulumi/pulumi/pull/15028/files#diff-52b25675ac0d98614d062fc1d1c9e60759f905cf7c60a9339402a62c23cc2c55L32-L33) - this PR replaces it. Fixes # (issue) ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [ ] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2024-01-23 19:15:29 +00:00
case apitype.StackImportUpdate, apitype.RenameUpdate:
contract.Failf("%s updates are not supported", kind)
default:
contract.Failf("Unknown kind: %s", kind)
}
path := getStackPath(stack, endpoint)
var updateResponse apitype.UpdateProgramResponse
if err := pc.restCall(ctx, "POST", path, nil, &updateRequest, &updateResponse); err != nil {
return UpdateIdentifier{}, CreateUpdateDetails{}, err
}
return UpdateIdentifier{
StackIdentifier: stack,
UpdateKind: kind,
UpdateID: updateResponse.UpdateID,
}, CreateUpdateDetails{
Messages: updateResponse.Messages,
RequiredPolicies: updateResponse.RequiredPolicies,
}, nil
}
// RenameStack renames the provided stack to have the new identifier.
func (pc *Client) RenameStack(ctx context.Context, currentID, newID StackIdentifier) error {
req := apitype.StackRenameRequest{
Add tokens.StackName (#14487) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> This adds a new type `tokens.StackName` which is a relatively strongly typed container for a stack name. The only weakly typed aspect of it is Go will always allow the "zero" value to be created for a struct, which for a stack name is the empty string which is invalid. To prevent introducing unexpected empty strings when working with stack names the `String()` method will panic for zero initialized stack names. Apart from the zero value, all other instances of `StackName` are via `ParseStackName` which returns a descriptive error if the string is not valid. This PR only updates "pkg/" to use this type. There are a number of places in "sdk/" which could do with this type as well, but there's no harm in doing a staggered roll out, and some parts of "sdk/" are user facing and will probably have to stay on the current `tokens.Name` and `tokens.QName` types. There are two places in the system where we panic on invalid stack names, both in the http backend. This _should_ be fine as we've had long standing validation that stacks created in the service are valid stack names. Just in case people have managed to introduce invalid stack names, there is the `PULUMI_DISABLE_VALIDATION` environment variable which will turn off the validation _and_ panicing for stack names. Users can use that to temporarily disable the validation and continue working, but it should only be seen as a temporary measure. If they have invalid names they should rename them, or if they think they should be valid raise an issue with us to change the validation code. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-15 07:44:54 +00:00
NewName: newID.Stack.String(),
NewProject: newID.Project,
}
return pc.restCall(ctx, "POST", getStackPath(currentID, "rename"), nil, &req, nil)
}
// StartUpdate starts the indicated update. It returns the new version of the update's target stack and the token used
// to authenticate operations on the update if any. Replaces the stack's tags with the updated set.
func (pc *Client) StartUpdate(ctx context.Context, update UpdateIdentifier,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
tags map[apitype.StackTagName]string,
) (int, string, error) {
// Validate names and tags.
Add tokens.StackName (#14487) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> This adds a new type `tokens.StackName` which is a relatively strongly typed container for a stack name. The only weakly typed aspect of it is Go will always allow the "zero" value to be created for a struct, which for a stack name is the empty string which is invalid. To prevent introducing unexpected empty strings when working with stack names the `String()` method will panic for zero initialized stack names. Apart from the zero value, all other instances of `StackName` are via `ParseStackName` which returns a descriptive error if the string is not valid. This PR only updates "pkg/" to use this type. There are a number of places in "sdk/" which could do with this type as well, but there's no harm in doing a staggered roll out, and some parts of "sdk/" are user facing and will probably have to stay on the current `tokens.Name` and `tokens.QName` types. There are two places in the system where we panic on invalid stack names, both in the http backend. This _should_ be fine as we've had long standing validation that stacks created in the service are valid stack names. Just in case people have managed to introduce invalid stack names, there is the `PULUMI_DISABLE_VALIDATION` environment variable which will turn off the validation _and_ panicing for stack names. Users can use that to temporarily disable the validation and continue working, but it should only be seen as a temporary measure. If they have invalid names they should rename them, or if they think they should be valid raise an issue with us to change the validation code. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-11-15 07:44:54 +00:00
if err := validation.ValidateStackTags(tags); err != nil {
return 0, "", fmt.Errorf("validating stack properties: %w", err)
}
req := apitype.StartUpdateRequest{
Tags: tags,
}
var resp apitype.StartUpdateResponse
if err := pc.restCall(ctx, "POST", getUpdatePath(update), nil, req, &resp); err != nil {
return 0, "", err
}
return resp.Version, resp.Token, nil
}
2020-01-16 20:04:51 +00:00
// ListPolicyGroups lists all `PolicyGroups` the organization has in the Pulumi service.
func (pc *Client) ListPolicyGroups(ctx context.Context, orgName string, inContToken *string) (
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
apitype.ListPolicyGroupsResponse, *string, error,
) {
// NOTE: The ListPolicyGroups API on the Pulumi Service is not currently paginated.
2020-01-16 20:04:51 +00:00
var resp apitype.ListPolicyGroupsResponse
err := pc.restCall(ctx, "GET", listPolicyGroupsPath(orgName), nil, nil, &resp)
if err != nil {
return resp, nil, fmt.Errorf("List Policy Groups failed: %w", err)
2020-01-16 20:04:51 +00:00
}
return resp, nil, nil
2020-01-16 20:04:51 +00:00
}
// ListPolicyPacks lists all `PolicyPack` the organization has in the Pulumi service.
func (pc *Client) ListPolicyPacks(ctx context.Context, orgName string, inContToken *string) (
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
apitype.ListPolicyPacksResponse, *string, error,
) {
// NOTE: The ListPolicyPacks API on the Pulumi Service is not currently paginated.
2020-01-16 20:04:51 +00:00
var resp apitype.ListPolicyPacksResponse
err := pc.restCall(ctx, "GET", listPolicyPacksPath(orgName), nil, nil, &resp)
if err != nil {
return resp, nil, fmt.Errorf("List Policy Packs failed: %w", err)
2020-01-16 20:04:51 +00:00
}
return resp, nil, nil
2020-01-16 20:04:51 +00:00
}
2020-02-25 01:11:56 +00:00
// PublishPolicyPack publishes a `PolicyPack` to the Pulumi service. If it successfully publishes
// the Policy Pack, it returns the version of the pack.
func (pc *Client) PublishPolicyPack(ctx context.Context, orgName string,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
analyzerInfo plugin.AnalyzerInfo, dirArchive io.Reader,
) (string, error) {
//
// Step 1: Send POST containing policy metadata to service. This begins process of creating
// publishing the PolicyPack.
//
2020-02-25 01:11:56 +00:00
if err := validatePolicyPackVersion(analyzerInfo.Version); err != nil {
return "", err
}
policies := make([]apitype.Policy, len(analyzerInfo.Policies))
for i, policy := range analyzerInfo.Policies {
configSchema, err := convertPolicyConfigSchema(policy.ConfigSchema)
if err != nil {
return "", err
}
policies[i] = apitype.Policy{
Name: policy.Name,
DisplayName: policy.DisplayName,
Description: policy.Description,
EnforcementLevel: policy.EnforcementLevel,
Message: policy.Message,
ConfigSchema: configSchema,
}
}
req := apitype.CreatePolicyPackRequest{
Name: analyzerInfo.Name,
DisplayName: analyzerInfo.DisplayName,
2020-02-25 01:11:56 +00:00
VersionTag: analyzerInfo.Version,
Policies: policies,
}
2020-02-25 01:11:56 +00:00
// Print a publishing message. We have to handle the case where an older version of pulumi/policy
// is in use, which does not provide a version tag.
var versionMsg string
if analyzerInfo.Version != "" {
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
versionMsg = " - version " + analyzerInfo.Version
2020-02-25 01:11:56 +00:00
}
fmt.Printf("Publishing %q%s to %q\n", analyzerInfo.Name, versionMsg, orgName)
var resp apitype.CreatePolicyPackResponse
err := pc.restCall(ctx, "POST", publishPolicyPackPath(orgName), nil, req, &resp)
if err != nil {
return "", fmt.Errorf("Publish policy pack failed: %w", err)
}
//
// Step 2: Upload the compressed PolicyPack directory to the pre-signed object storage service URL.
// The PolicyPack is now published.
//
putReq, err := http.NewRequest(http.MethodPut, resp.UploadURI, dirArchive)
if err != nil {
return "", fmt.Errorf("Failed to upload compressed PolicyPack: %w", err)
}
for k, v := range resp.RequiredHeaders {
putReq.Header.Add(k, v)
}
_, err = pc.httpClient.Do(putReq)
if err != nil {
return "", fmt.Errorf("Failed to upload compressed PolicyPack: %w", err)
}
//
// Step 3: Signal to the service that the PolicyPack publish operation is complete.
//
2020-02-25 01:11:56 +00:00
// If the version tag is empty, an older version of pulumi/policy is being used and
// we therefore need to use the version provided by the pulumi service.
version := analyzerInfo.Version
if version == "" {
version = strconv.Itoa(resp.Version)
fmt.Printf("Published as version %s\n", version)
}
err = pc.restCall(ctx, "POST",
2020-02-25 01:11:56 +00:00
publishPolicyPackPublishComplete(orgName, analyzerInfo.Name, version), nil, nil, nil)
if err != nil {
return "", fmt.Errorf("Request to signal completion of the publish operation failed: %w", err)
}
2020-02-25 01:11:56 +00:00
return version, nil
}
// convertPolicyConfigSchema converts a policy's schema from the analyzer to the apitype.
func convertPolicyConfigSchema(schema *plugin.AnalyzerPolicyConfigSchema) (*apitype.PolicyConfigSchema, error) {
if schema == nil {
return nil, nil
}
properties := map[string]*json.RawMessage{}
for k, v := range schema.Properties {
bytes, err := json.Marshal(v)
if err != nil {
return nil, err
}
raw := json.RawMessage(bytes)
properties[k] = &raw
}
return &apitype.PolicyConfigSchema{
Type: apitype.Object,
Properties: properties,
Required: schema.Required,
}, nil
}
2020-02-25 01:11:56 +00:00
// validatePolicyPackVersion validates the version of a Policy Pack. The version may be empty,
// as it is likely an older version of pulumi/policy that does not gather the version.
func validatePolicyPackVersion(s string) error {
if s == "" {
return nil
}
policyPackVersionTagRE := regexp.MustCompile("^[a-zA-Z0-9-_.]{1,100}$")
if !policyPackVersionTagRE.MatchString(s) {
msg := fmt.Sprintf("invalid version %q - version may only contain alphanumeric, hyphens, or underscores. "+
"It must also be between 1 and 100 characters long.", s)
return errors.New(msg)
}
return nil
}
2020-01-03 22:16:39 +00:00
// ApplyPolicyPack enables a `PolicyPack` to the Pulumi organization. If policyGroup is not empty,
// it will enable the PolicyPack on the default PolicyGroup.
2020-02-25 01:11:56 +00:00
func (pc *Client) ApplyPolicyPack(ctx context.Context, orgName, policyGroup,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
policyPackName, versionTag string, policyPackConfig map[string]*json.RawMessage,
) error {
// If a Policy Group was not specified, we use the default Policy Group.
2020-01-03 22:16:39 +00:00
if policyGroup == "" {
policyGroup = apitype.DefaultPolicyGroup
2020-01-03 22:16:39 +00:00
}
req := apitype.UpdatePolicyGroupRequest{
AddPolicyPack: &apitype.PolicyPackMetadata{
2020-02-25 01:11:56 +00:00
Name: policyPackName,
VersionTag: versionTag,
Config: policyPackConfig,
2020-01-03 22:16:39 +00:00
},
}
err := pc.restCall(ctx, http.MethodPatch, updatePolicyGroupPath(orgName, policyGroup), nil, req, nil)
2019-06-28 17:07:49 +00:00
if err != nil {
return fmt.Errorf("Enable policy pack failed: %w", err)
2019-06-28 17:07:49 +00:00
}
2020-01-03 22:16:39 +00:00
return nil
}
2019-06-28 17:07:49 +00:00
// GetPolicyPackSchema gets Policy Pack config schema.
func (pc *Client) GetPolicyPackSchema(ctx context.Context, orgName,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
policyPackName, versionTag string,
) (*apitype.GetPolicyPackConfigSchemaResponse, error) {
var resp apitype.GetPolicyPackConfigSchemaResponse
err := pc.restCall(ctx, http.MethodGet,
getPolicyPackConfigSchemaPath(orgName, policyPackName, versionTag), nil, nil, &resp)
if err != nil {
return nil, fmt.Errorf("Retrieving policy pack config schema failed: %w", err)
}
return &resp, nil
}
2020-01-03 22:16:39 +00:00
// DisablePolicyPack disables a `PolicyPack` to the Pulumi organization. If policyGroup is not empty,
// it will disable the PolicyPack on the default PolicyGroup.
func (pc *Client) DisablePolicyPack(ctx context.Context, orgName string, policyGroup string,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
policyPackName, versionTag string,
) error {
2020-01-03 22:16:39 +00:00
// If Policy Group was not specified, use the default Policy Group.
if policyGroup == "" {
policyGroup = apitype.DefaultPolicyGroup
}
req := apitype.UpdatePolicyGroupRequest{
RemovePolicyPack: &apitype.PolicyPackMetadata{
2020-02-25 01:11:56 +00:00
Name: policyPackName,
VersionTag: versionTag,
2020-01-03 22:16:39 +00:00
},
}
err := pc.restCall(ctx, http.MethodPatch, updatePolicyGroupPath(orgName, policyGroup), nil, req, nil)
if err != nil {
return fmt.Errorf("Request to disable policy pack failed: %w", err)
2020-01-03 22:16:39 +00:00
}
return nil
}
2020-01-27 18:35:34 +00:00
// RemovePolicyPack removes all versions of a `PolicyPack` from the Pulumi organization.
func (pc *Client) RemovePolicyPack(ctx context.Context, orgName string, policyPackName string) error {
path := deletePolicyPackPath(orgName, policyPackName)
err := pc.restCall(ctx, http.MethodDelete, path, nil, nil, nil)
if err != nil {
return fmt.Errorf("Request to remove policy pack failed: %w", err)
2020-01-27 18:35:34 +00:00
}
return nil
}
// RemovePolicyPackByVersion removes a specific version of a `PolicyPack` from
// the Pulumi organization.
func (pc *Client) RemovePolicyPackByVersion(ctx context.Context, orgName string,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
policyPackName string, versionTag string,
) error {
2020-02-25 01:11:56 +00:00
path := deletePolicyPackVersionPath(orgName, policyPackName, versionTag)
2020-01-03 22:16:39 +00:00
err := pc.restCall(ctx, http.MethodDelete, path, nil, nil, nil)
if err != nil {
return fmt.Errorf("Request to remove policy pack failed: %w", err)
2020-01-03 22:16:39 +00:00
}
2019-06-28 17:07:49 +00:00
return nil
}
// DownloadPolicyPack applies a `PolicyPack` to the Pulumi organization.
func (pc *Client) DownloadPolicyPack(ctx context.Context, url string) (io.ReadCloser, error) {
getS3Req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, fmt.Errorf("Failed to download compressed PolicyPack: %w", err)
}
resp, err := pc.httpClient.Do(getS3Req)
if err != nil {
return nil, fmt.Errorf("Failed to download compressed PolicyPack: %w", err)
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("Failed to download compressed PolicyPack: %s", resp.Status)
}
return resp.Body, nil
}
// GetUpdateEvents returns all events, taking an optional continuation token from a previous call.
func (pc *Client) GetUpdateEvents(ctx context.Context, update UpdateIdentifier,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
continuationToken *string,
) (apitype.UpdateResults, error) {
path := getUpdatePath(update)
if continuationToken != nil {
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
path += "?continuationToken=" + *continuationToken
}
var results apitype.UpdateResults
if err := pc.restCall(ctx, "GET", path, nil, nil, &results); err != nil {
return apitype.UpdateResults{}, err
}
return results, nil
}
// RenewUpdateLease renews the indicated update lease for the given duration.
func (pc *Client) RenewUpdateLease(ctx context.Context, update UpdateIdentifier, token string,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
duration time.Duration,
) (string, error) {
req := apitype.RenewUpdateLeaseRequest{
Duration: int(duration / time.Second),
}
var resp apitype.RenewUpdateLeaseResponse
// While renewing a lease uses POST, it is safe to send multiple requests (consider that we do this multiple times
// during a long running update). Since we would fail our update operation if we can't renew our lease, we'll retry
// these POST operations.
if err := pc.updateRESTCall(ctx, "POST", getUpdatePath(update, "renew_lease"), nil, req, &resp,
updateAccessToken(updateTokenStaticSource(token)), httpCallOptions{RetryPolicy: retryAllMethods}); err != nil {
return "", err
}
return resp.Token, nil
}
// InvalidateUpdateCheckpoint invalidates the checkpoint for the indicated update.
2023-03-01 22:23:20 +00:00
func (pc *Client) InvalidateUpdateCheckpoint(ctx context.Context, update UpdateIdentifier,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
token UpdateTokenSource,
) error {
req := apitype.PatchUpdateCheckpointRequest{
IsInvalid: true,
}
// It is safe to retry this PATCH operation, because it is logically idempotent.
return pc.updateRESTCall(ctx, "PATCH", getUpdatePath(update, "checkpoint"), nil, req, nil,
updateAccessToken(token), httpCallOptions{RetryPolicy: retryAllMethods})
}
// PatchUpdateCheckpoint patches the checkpoint for the indicated update with the given contents.
Implement more precise delete-before-replace semantics. (#2369) This implements the new algorithm for deciding which resources must be deleted due to a delete-before-replace operation. We need to compute the set of resources that may be replaced by a change to the resource under consideration. We do this by taking the complete set of transitive dependents on the resource under consideration and removing any resources that would not be replaced by changes to their dependencies. We determine whether or not a resource may be replaced by substituting unknowns for input properties that may change due to deletion of the resources their value depends on and calling the resource provider's Diff method. This is perhaps clearer when described by example. Consider the following dependency graph: A __|__ B C | _|_ D E F In this graph, all of B, C, D, E, and F transitively depend on A. It may be the case, however, that changes to the specific properties of any of those resources R that would occur if a resource on the path to A were deleted and recreated may not cause R to be replaced. For example, the edge from B to A may be a simple dependsOn edge such that a change to B does not actually influence any of B's input properties. In that case, neither B nor D would need to be deleted before A could be deleted. In order to make the above algorithm a reality, the resource monitor interface has been updated to include a map that associates an input property key with the list of resources that input property depends on. Older clients of the resource monitor will leave this map empty, in which case all input properties will be treated as depending on all dependencies of the resource. This is probably overly conservative, but it is less conservative than what we currently implement, and is certainly correct.
2019-01-28 17:46:30 +00:00
func (pc *Client) PatchUpdateCheckpoint(ctx context.Context, update UpdateIdentifier, deployment *apitype.DeploymentV3,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
token UpdateTokenSource,
) error {
rawDeployment, err := json.Marshal(deployment)
if err != nil {
return err
}
req := apitype.PatchUpdateCheckpointRequest{
Implement more precise delete-before-replace semantics. (#2369) This implements the new algorithm for deciding which resources must be deleted due to a delete-before-replace operation. We need to compute the set of resources that may be replaced by a change to the resource under consideration. We do this by taking the complete set of transitive dependents on the resource under consideration and removing any resources that would not be replaced by changes to their dependencies. We determine whether or not a resource may be replaced by substituting unknowns for input properties that may change due to deletion of the resources their value depends on and calling the resource provider's Diff method. This is perhaps clearer when described by example. Consider the following dependency graph: A __|__ B C | _|_ D E F In this graph, all of B, C, D, E, and F transitively depend on A. It may be the case, however, that changes to the specific properties of any of those resources R that would occur if a resource on the path to A were deleted and recreated may not cause R to be replaced. For example, the edge from B to A may be a simple dependsOn edge such that a change to B does not actually influence any of B's input properties. In that case, neither B nor D would need to be deleted before A could be deleted. In order to make the above algorithm a reality, the resource monitor interface has been updated to include a map that associates an input property key with the list of resources that input property depends on. Older clients of the resource monitor will leave this map empty, in which case all input properties will be treated as depending on all dependencies of the resource. This is probably overly conservative, but it is less conservative than what we currently implement, and is certainly correct.
2019-01-28 17:46:30 +00:00
Version: 3,
Deployment: rawDeployment,
}
// It is safe to retry this PATCH operation, because it is logically idempotent, since we send the entire
// deployment instead of a set of changes to apply.
return pc.updateRESTCall(ctx, "PATCH", getUpdatePath(update, "checkpoint"), nil, req, nil,
updateAccessToken(token), httpCallOptions{RetryPolicy: retryAllMethods, GzipCompress: true})
}
// PatchUpdateCheckpointVerbatim is a variant of PatchUpdateCheckpoint that preserves JSON indentation of the
// UntypedDeployment transferred over the wire.
func (pc *Client) PatchUpdateCheckpointVerbatim(ctx context.Context, update UpdateIdentifier,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
sequenceNumber int, untypedDeploymentBytes json.RawMessage, token UpdateTokenSource,
) error {
req := apitype.PatchUpdateVerbatimCheckpointRequest{
Version: 3,
UntypedDeployment: untypedDeploymentBytes,
SequenceNumber: sequenceNumber,
}
reqPayload, err := marshalVerbatimCheckpointRequest(req)
if err != nil {
return err
}
// It is safe to retry this PATCH operation, because it is logically idempotent, since we send the entire
// deployment instead of a set of changes to apply.
return pc.updateRESTCall(ctx, "PATCH", getUpdatePath(update, "checkpointverbatim"), nil, reqPayload, nil,
updateAccessToken(token), httpCallOptions{RetryPolicy: retryAllMethods, GzipCompress: true})
}
// PatchUpdateCheckpointDelta patches the checkpoint for the indicated update with the given contents, just like
// PatchUpdateCheckpoint. Unlike PatchUpdateCheckpoint, it uses a text diff-based protocol to conserve bandwidth on
// large stack states.
func (pc *Client) PatchUpdateCheckpointDelta(ctx context.Context, update UpdateIdentifier,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
sequenceNumber int, checkpointHash string, deploymentDelta json.RawMessage, token UpdateTokenSource,
) error {
req := apitype.PatchUpdateCheckpointDeltaRequest{
Version: 3,
CheckpointHash: checkpointHash,
SequenceNumber: sequenceNumber,
DeploymentDelta: deploymentDelta,
}
// It is safe to retry because SequenceNumber serves as an idempotency key.
return pc.updateRESTCall(ctx, "PATCH", getUpdatePath(update, "checkpointdelta"), nil, req, nil,
updateAccessToken(token), httpCallOptions{RetryPolicy: retryAllMethods, GzipCompress: true})
}
// CancelUpdate cancels the indicated update.
func (pc *Client) CancelUpdate(ctx context.Context, update UpdateIdentifier) error {
// It is safe to retry this PATCH operation, because it is logically idempotent.
return pc.restCallWithOptions(ctx, "POST", getUpdatePath(update, "cancel"), nil, nil, nil,
httpCallOptions{RetryPolicy: retryAllMethods})
}
// CompleteUpdate completes the indicated update with the given status.
func (pc *Client) CompleteUpdate(ctx context.Context, update UpdateIdentifier, status apitype.UpdateStatus,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
token UpdateTokenSource,
) error {
req := apitype.CompleteUpdateRequest{
Status: status,
}
// It is safe to retry this PATCH operation, because it is logically idempotent.
return pc.updateRESTCall(ctx, "POST", getUpdatePath(update, "complete"), nil, req, nil,
updateAccessToken(token), httpCallOptions{RetryPolicy: retryAllMethods})
}
// GetUpdateEngineEvents returns the engine events for an update.
func (pc *Client) GetUpdateEngineEvents(ctx context.Context, update UpdateIdentifier,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
continuationToken *string,
) (apitype.GetUpdateEventsResponse, error) {
path := getUpdatePath(update, "events")
if continuationToken != nil {
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
path += "?continuationToken=" + *continuationToken
}
var resp apitype.GetUpdateEventsResponse
if err := pc.restCall(ctx, "GET", path, nil, nil, &resp); err != nil {
return apitype.GetUpdateEventsResponse{}, err
}
return resp, nil
}
// RecordEngineEvents posts a batch of engine events to the Pulumi service.
func (pc *Client) RecordEngineEvents(
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
ctx context.Context, update UpdateIdentifier, batch apitype.EngineEventBatch, token UpdateTokenSource,
) error {
callOpts := httpCallOptions{
GzipCompress: true,
RetryPolicy: retryAllMethods,
}
return pc.updateRESTCall(
ctx, "POST", getUpdatePath(update, "events/batch"),
nil, batch, nil,
updateAccessToken(token), callOpts)
}
// UpdateStackTags updates the stacks's tags, replacing all existing tags.
func (pc *Client) UpdateStackTags(
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
ctx context.Context, stack StackIdentifier, tags map[apitype.StackTagName]string,
) error {
// Validate stack tags.
if err := validation.ValidateStackTags(tags); err != nil {
return err
}
return pc.restCall(ctx, "PATCH", getStackPath(stack, "tags"), nil, tags, nil)
}
func (pc *Client) UpdateStackDeploymentSettings(ctx context.Context, stack StackIdentifier,
deployment apitype.DeploymentSettings,
) error {
return pc.restCall(ctx, "PUT", getStackPath(stack, "deployments", "settings"), nil, deployment, nil)
}
func (pc *Client) EncryptStackDeploymentSettingsSecret(ctx context.Context,
stack StackIdentifier, secret string,
) (*apitype.SecretValue, error) {
request := apitype.SecretValue{Value: secret}
response := apitype.SecretValue{}
err := pc.restCall(ctx, "POST", getStackPath(stack, "deployments", "settings", "encrypt"), nil, &request, &response)
if err != nil {
return nil, err
}
return &response, nil
}
func (pc *Client) DestroyStackDeploymentSettings(ctx context.Context, stack StackIdentifier) error {
return pc.restCall(ctx, "DELETE", getStackPath(stack, "deployments", "settings"), nil, nil, nil)
}
func (pc *Client) GetStackDeploymentSettings(ctx context.Context,
stack StackIdentifier,
) (*apitype.DeploymentSettings, error) {
var response apitype.DeploymentSettings
err := pc.restCall(ctx, "GET", getStackPath(stack, "deployments", "settings"), nil, nil, &response)
return &response, err
}
func getDeploymentPath(stack StackIdentifier, components ...string) string {
Use new API for deployments (#15684) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Updates Remote Automation API to use the new stable URLs for the Deployments API. Adds support for `inheritSettings` to allow inheriting deployment settings pre-existing on the stack. I've tested this manually by editing the automation-api-examples for remote deployments, but not sure of a great way to add automated tests since automation api doesn't yet have support for setting deployment settings. EDIT: I considered just setting up a static stack for this but abandoned it because of concerns around parallel runs. We can add automated tests for this once we support creating deployment settings with automation api (coming soon). Fixes #12739 Fixes #15518 ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2024-04-16 23:23:56 +00:00
prefix := fmt.Sprintf("/api/stacks/%s/%s/%s/deployments", stack.Owner, stack.Project, stack.Stack)
return path.Join(append([]string{prefix}, components...)...)
}
func (pc *Client) CreateDeployment(ctx context.Context, stack StackIdentifier,
req apitype.CreateDeploymentRequest, deploymentInitiator string,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
) (*apitype.CreateDeploymentResponse, error) {
var resp apitype.CreateDeploymentResponse
err := pc.restCallWithOptions(ctx, http.MethodPost, getDeploymentPath(stack), nil, req, &resp, httpCallOptions{
Header: map[string][]string{
"X-Pulumi-Deployment-Initiator": {deploymentInitiator},
},
})
if err != nil {
return nil, fmt.Errorf("creating deployment failed: %w", err)
}
return &resp, nil
}
func (pc *Client) GetDeploymentLogs(ctx context.Context, stack StackIdentifier, id,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
token string,
) (*apitype.DeploymentLogs, error) {
Enable perfsprint linter (#14813) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Prompted by a comment in another review: https://github.com/pulumi/pulumi/pull/14654#discussion_r1419995945 This lints that we don't use `fmt.Errorf` when `errors.New` will suffice, it also covers a load of other cases where `Sprintf` is sub-optimal. Most of these edits were made by running `perfsprint --fix`. ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [ ] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-12-12 12:19:42 +00:00
path := getDeploymentPath(stack, id, "logs?continuationToken="+token)
var resp apitype.DeploymentLogs
err := pc.restCall(ctx, http.MethodGet, path, nil, nil, &resp)
if err != nil {
return nil, fmt.Errorf("getting deployment %s logs failed: %w", id, err)
}
return &resp, nil
}
func (pc *Client) GetDeploymentUpdates(ctx context.Context, stack StackIdentifier,
all: Reformat with gofumpt Per team discussion, switching to gofumpt. [gofumpt][1] is an alternative, stricter alternative to gofmt. It addresses other stylistic concerns that gofmt doesn't yet cover. [1]: https://github.com/mvdan/gofumpt See the full list of [Added rules][2], but it includes: - Dropping empty lines around function bodies - Dropping unnecessary variable grouping when there's only one variable - Ensuring an empty line between multi-line functions - simplification (`-s` in gofmt) is always enabled - Ensuring multi-line function signatures end with `) {` on a separate line. [2]: https://github.com/mvdan/gofumpt#Added-rules gofumpt is stricter, but there's no lock-in. All gofumpt output is valid gofmt output, so if we decide we don't like it, it's easy to switch back without any code changes. gofumpt support is built into the tooling we use for development so this won't change development workflows. - golangci-lint includes a gofumpt check (enabled in this PR) - gopls, the LSP for Go, includes a gofumpt option (see [installation instrutions][3]) [3]: https://github.com/mvdan/gofumpt#installation This change was generated by running: ```bash gofumpt -w $(rg --files -g '*.go' | rg -v testdata | rg -v compilation_error) ``` The following files were manually tweaked afterwards: - pkg/cmd/pulumi/stack_change_secrets_provider.go: one of the lines overflowed and had comments in an inconvenient place - pkg/cmd/pulumi/destroy.go: `var x T = y` where `T` wasn't necessary - pkg/cmd/pulumi/policy_new.go: long line because of error message - pkg/backend/snapshot_test.go: long line trying to assign three variables in the same assignment I have included mention of gofumpt in the CONTRIBUTING.md.
2023-03-03 16:36:39 +00:00
id string,
) ([]apitype.GetDeploymentUpdatesUpdateInfo, error) {
path := getDeploymentPath(stack, id, "updates")
var resp []apitype.GetDeploymentUpdatesUpdateInfo
err := pc.restCall(ctx, http.MethodGet, path, nil, nil, &resp)
if err != nil {
return nil, fmt.Errorf("getting deployment %s updates failed: %w", id, err)
}
return resp, nil
}
2022-11-21 16:26:09 +00:00
func (pc *Client) GetCapabilities(ctx context.Context) (*apitype.CapabilitiesResponse, error) {
2022-11-22 16:47:45 +00:00
if pc.DisableCapabilityProbing {
return &apitype.CapabilitiesResponse{}, nil
}
2022-11-21 16:26:09 +00:00
var resp apitype.CapabilitiesResponse
err := pc.restCall(ctx, http.MethodGet, "/api/capabilities", nil, nil, &resp)
if is404(err) {
// The client continues to support legacy backends. They do not support /api/capabilities and are
// assumed here to have no additional capabilities.
return &apitype.CapabilitiesResponse{}, nil
}
if err != nil {
return nil, fmt.Errorf("querying capabilities failed: %w", err)
}
return &resp, nil
}
Adds two new CLI features - search and AI search (#13611) Adds initial pulumi search implementation <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/13489 Fixes https://github.com/pulumi/pulumi/issues/12868 ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-08-21 15:06:46 +00:00
func getSearchPath(orgName string) string {
return fmt.Sprintf("/api/orgs/%s/search/resources", url.PathEscape(orgName))
}
func getNaturalLanguageSearchPath(orgName string) string {
return fmt.Sprintf("/api/orgs/%s/search/resources/parse", url.PathEscape(orgName))
}
[org search] Adds both the display of and the ability to open search results URLs (#13879) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Displays to users a copyable URL to view org search results in Pulumi Cloud as well as a `--web` flag to automatically open those results for them. Fixes https://github.com/pulumi/pulumi.ai/issues/207 ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-11 16:33:56 +00:00
func getPulumiOrgSearchPath(baseURL string, orgName string) string {
return fmt.Sprintf("%s/%s/resources", baseURL, url.PathEscape(orgName))
}
Adds two new CLI features - search and AI search (#13611) Adds initial pulumi search implementation <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/13489 Fixes https://github.com/pulumi/pulumi/issues/12868 ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-08-21 15:06:46 +00:00
// Pulumi Cloud Search Functions
func (pc *Client) GetSearchQueryResults(
[org search] Adds both the display of and the ability to open search results URLs (#13879) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Displays to users a copyable URL to view org search results in Pulumi Cloud as well as a `--web` flag to automatically open those results for them. Fixes https://github.com/pulumi/pulumi.ai/issues/207 ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-11 16:33:56 +00:00
ctx context.Context, orgName string, queryParams *apitype.PulumiQueryRequest, baseURL string,
Adds two new CLI features - search and AI search (#13611) Adds initial pulumi search implementation <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/13489 Fixes https://github.com/pulumi/pulumi/issues/12868 ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-08-21 15:06:46 +00:00
) (*apitype.ResourceSearchResponse, error) {
var resp apitype.ResourceSearchResponse
err := pc.restCall(ctx, http.MethodGet, getSearchPath(orgName), queryParams, nil, &resp)
if err != nil {
return nil, fmt.Errorf("querying search failed: %w", err)
}
[org search] Adds both the display of and the ability to open search results URLs (#13879) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Displays to users a copyable URL to view org search results in Pulumi Cloud as well as a `--web` flag to automatically open those results for them. Fixes https://github.com/pulumi/pulumi.ai/issues/207 ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-09-11 16:33:56 +00:00
resp.URL = fmt.Sprintf("%s?query=%s", getPulumiOrgSearchPath(baseURL, orgName), url.QueryEscape(queryParams.Query))
Adds two new CLI features - search and AI search (#13611) Adds initial pulumi search implementation <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Fixes https://github.com/pulumi/pulumi/issues/13489 Fixes https://github.com/pulumi/pulumi/issues/12868 ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2023-08-21 15:06:46 +00:00
return &resp, nil
}
func (pc *Client) GetNaturalLanguageQueryResults(
ctx context.Context, orgName string, queryString string,
) (*apitype.PulumiQueryResponse, error) {
var resp apitype.PulumiQueryResponse
queryParamObject := apitype.PulumiQueryRequest{
Query: queryString,
}
err := pc.restCall(ctx, http.MethodGet, getNaturalLanguageSearchPath(orgName), queryParamObject, nil, &resp)
if err != nil {
return nil, fmt.Errorf("querying search failed: %w", err)
}
return &resp, nil
}
2022-11-21 16:26:09 +00:00
func is404(err error) bool {
if err == nil {
return false
}
2022-11-22 16:51:47 +00:00
var errResp *apitype.ErrorResponse
if errors.As(err, &errResp) && errResp.Code == http.StatusNotFound {
2022-11-21 16:26:09 +00:00
return true
}
return false
}
Adds Pulumi AI integrations with Pulumi New (#14685) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description <!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. --> Now that we support .zip archive sources for Pulumi New, we have all of the API surface we need to provide a full Pulumi New experience using Pulumi AI. This PR introduces a few modes of interacting with Pulumi AI to generate Pulumi projects. - The default `pulumi new` experience now begins with a choice between `ai` and `template` modes - the `template` mode represents the current state of running `pulumi new`, while `ai` provides an interactive experience with Pulumi AI. - The user can iteratively ask questions to improve or change the resulting program - each time a prompt is completed, they are asked to `refine`, `no`, or `yes` their session - `refine` allows a follow-on prompt to be submitted. `no` ends the session without generating a pulumi project, and `yes` generates a Pulumi project from the most recent program returned by Pulumi AI. - Additionally, top-level flags, `--ai` and `--language` are provided to fill in default values for the AI mode. When a prompt is provided with a language, it is automatically submitted to Pulumi AI - if either is missing, the user is prompted for whichever value is missing. Fixes https://github.com/pulumi/pulumi.ai/issues/441 Fixes https://github.com/pulumi/pulumi.ai/issues/443 Fixes https://github.com/pulumi/pulumi.ai/issues/444 Depends on https://github.com/pulumi/pulumi.ai/pull/472 Depends on https://github.com/pulumi/pulumi.ai/pull/507 Depends on https://github.com/pulumi/pulumi.ai/pull/508 ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. --> --------- Co-authored-by: Aaron Friel <mayreply@aaronfriel.com>
2023-12-20 22:08:09 +00:00
// SubmitAIPrompt sends the user's prompt to the Pulumi Service and streams back the response.
func (pc *Client) SubmitAIPrompt(ctx context.Context, requestBody interface{}) (*http.Response, error) {
url, err := url.Parse(pc.apiURL + getAIPromptPath())
if err != nil {
return nil, err
}
marshalledBody, err := json.Marshal(requestBody)
if err != nil {
return nil, err
}
request, err := http.NewRequestWithContext(ctx, http.MethodPost, url.String(), bytes.NewReader(marshalledBody))
if err != nil {
return nil, err
}
request.Header.Add("Authorization", fmt.Sprintf("token %s", pc.apiToken))
res, err := pc.do(ctx, request)
return res, err
}