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.
|
2019-08-12 09:12:17 +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 backend
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2023-06-26 22:04:24 +00:00
|
|
|
"strings"
|
2023-10-10 01:35:39 +00:00
|
|
|
"time"
|
2019-08-12 09:12:17 +00:00
|
|
|
|
2023-10-10 01:35:39 +00:00
|
|
|
"github.com/pulumi/esc"
|
2023-09-18 11:01:28 +00:00
|
|
|
sdkDisplay "github.com/pulumi/pulumi/pkg/v3/display"
|
2023-12-05 08:32:40 +00:00
|
|
|
"github.com/pulumi/pulumi/pkg/v3/engine"
|
2021-03-17 13:20:05 +00:00
|
|
|
"github.com/pulumi/pulumi/pkg/v3/operations"
|
|
|
|
"github.com/pulumi/pulumi/pkg/v3/resource/deploy"
|
2022-08-18 14:31:34 +00:00
|
|
|
"github.com/pulumi/pulumi/pkg/v3/secrets"
|
2021-03-17 13:20:05 +00:00
|
|
|
"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/resource/config"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/tokens"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/util/result"
|
2023-01-12 15:33:17 +00:00
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/workspace"
|
2019-08-12 09:12:17 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
//
|
|
|
|
// Mock backend.
|
|
|
|
//
|
|
|
|
|
|
|
|
type MockBackend struct {
|
2021-07-29 20:37:17 +00:00
|
|
|
NameF func() string
|
|
|
|
URLF func() string
|
2023-03-03 20:32:42 +00:00
|
|
|
SetCurrentProjectF func(proj *workspace.Project)
|
2021-07-29 20:37:17 +00:00
|
|
|
GetPolicyPackF func(ctx context.Context, policyPack string, d diag.Sink) (PolicyPack, error)
|
2022-03-23 22:05:26 +00:00
|
|
|
SupportsTagsF func() bool
|
2021-07-29 20:37:17 +00:00
|
|
|
SupportsOrganizationsF func() bool
|
2023-10-27 07:33:07 +00:00
|
|
|
SupportsProgressF func() bool
|
2021-07-29 20:37:17 +00:00
|
|
|
ParseStackReferenceF func(s string) (StackReference, error)
|
2024-06-13 19:49:49 +00:00
|
|
|
SupportsDeploymentsF func() bool
|
2021-07-29 20:37:17 +00:00
|
|
|
ValidateStackNameF func(s string) error
|
2023-06-21 15:46:54 +00:00
|
|
|
DoesProjectExistF func(context.Context, string, string) (bool, error)
|
2021-07-29 20:37:17 +00:00
|
|
|
GetStackF func(context.Context, StackReference) (Stack, error)
|
2023-03-20 21:12:17 +00:00
|
|
|
CreateStackF func(context.Context, StackReference, string, *CreateStackOptions) (Stack, error)
|
2021-07-29 20:37:17 +00:00
|
|
|
RemoveStackF func(context.Context, Stack, bool) (bool, error)
|
|
|
|
ListStacksF func(context.Context, ListStacksFilter, ContinuationToken) (
|
|
|
|
[]StackSummary, ContinuationToken, error)
|
2024-06-13 19:49:49 +00:00
|
|
|
RenameStackF func(context.Context, Stack, tokens.QName) (StackReference, error)
|
|
|
|
GetStackCrypterF func(StackReference) (config.Crypter, error)
|
|
|
|
QueryF func(context.Context, QueryOperation) error
|
|
|
|
GetLatestConfigurationF func(context.Context, Stack) (config.Map, error)
|
|
|
|
GetHistoryF func(context.Context, StackReference, int, int) ([]UpdateInfo, error)
|
|
|
|
UpdateStackTagsF func(context.Context, Stack, map[apitype.StackTagName]string) error
|
|
|
|
ExportDeploymentF func(context.Context, Stack) (*apitype.UntypedDeployment, error)
|
|
|
|
ImportDeploymentF func(context.Context, Stack, *apitype.UntypedDeployment) error
|
|
|
|
EncryptStackDeploymentSettingsSecretF func(ctx context.Context, stack Stack, secret string) (string, error)
|
|
|
|
UpdateStackDeploymentSettingsF func(context.Context, Stack, apitype.DeploymentSettings) error
|
|
|
|
DestroyStackDeploymentSettingsF func(ctx context.Context, stack Stack) error
|
|
|
|
GetStackDeploymentSettingsF func(context.Context, Stack) (*apitype.DeploymentSettings, error)
|
|
|
|
CurrentUserF func() (string, []string, *workspace.TokenInformation, error)
|
|
|
|
PreviewF func(context.Context, Stack,
|
2022-06-27 14:08:06 +00:00
|
|
|
UpdateOperation) (*deploy.Plan, sdkDisplay.ResourceChanges, result.Result)
|
2019-10-14 21:30:42 +00:00
|
|
|
UpdateF func(context.Context, Stack,
|
2022-06-27 14:08:06 +00:00
|
|
|
UpdateOperation) (sdkDisplay.ResourceChanges, result.Result)
|
2020-10-14 11:51:53 +00:00
|
|
|
ImportF func(context.Context, Stack,
|
2022-06-27 14:08:06 +00:00
|
|
|
UpdateOperation, []deploy.Import) (sdkDisplay.ResourceChanges, result.Result)
|
2019-10-14 21:30:42 +00:00
|
|
|
RefreshF func(context.Context, Stack,
|
2022-06-27 14:08:06 +00:00
|
|
|
UpdateOperation) (sdkDisplay.ResourceChanges, result.Result)
|
2019-10-14 21:30:42 +00:00
|
|
|
DestroyF func(context.Context, Stack,
|
2022-06-27 14:08:06 +00:00
|
|
|
UpdateOperation) (sdkDisplay.ResourceChanges, result.Result)
|
2019-11-06 20:56:29 +00:00
|
|
|
WatchF func(context.Context, Stack,
|
2021-06-21 07:34:21 +00:00
|
|
|
UpdateOperation, []string) result.Result
|
2023-01-11 16:04:14 +00:00
|
|
|
GetLogsF func(context.Context, secrets.Provider, Stack, StackConfiguration,
|
2019-08-12 09:12:17 +00:00
|
|
|
operations.LogQuery) ([]operations.LogEntry, error)
|
2022-03-03 17:07:05 +00:00
|
|
|
|
|
|
|
CancelCurrentUpdateF func(ctx context.Context, stackRef StackReference) error
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var _ Backend = (*MockBackend)(nil)
|
|
|
|
|
|
|
|
func (be *MockBackend) Name() string {
|
|
|
|
if be.NameF != nil {
|
|
|
|
return be.NameF()
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (be *MockBackend) URL() string {
|
|
|
|
if be.URLF != nil {
|
|
|
|
return be.URLF()
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2023-03-03 20:32:42 +00:00
|
|
|
func (be *MockBackend) SetCurrentProject(project *workspace.Project) {
|
|
|
|
if be.SetCurrentProjectF != nil {
|
|
|
|
be.SetCurrentProjectF(project)
|
2024-01-24 16:47:12 +00:00
|
|
|
return
|
2023-03-03 20:32:42 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2021-07-29 20:37:17 +00:00
|
|
|
func (be *MockBackend) ListPolicyGroups(context.Context, string, ContinuationToken) (
|
2023-03-03 16:36:39 +00:00
|
|
|
apitype.ListPolicyGroupsResponse, ContinuationToken, error,
|
|
|
|
) {
|
2020-01-16 20:04:51 +00:00
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2021-07-29 20:37:17 +00:00
|
|
|
func (be *MockBackend) ListPolicyPacks(context.Context, string, ContinuationToken) (
|
2023-03-03 16:36:39 +00:00
|
|
|
apitype.ListPolicyPacksResponse, ContinuationToken, error,
|
|
|
|
) {
|
2020-01-16 20:04:51 +00:00
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2019-08-12 09:12:17 +00:00
|
|
|
func (be *MockBackend) GetPolicyPack(
|
2023-03-03 16:36:39 +00:00
|
|
|
ctx context.Context, policyPack string, d diag.Sink,
|
|
|
|
) (PolicyPack, error) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if be.GetPolicyPackF != nil {
|
|
|
|
return be.GetPolicyPackF(ctx, policyPack, d)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2022-03-23 22:05:26 +00:00
|
|
|
func (be *MockBackend) SupportsTags() bool {
|
|
|
|
if be.SupportsTagsF != nil {
|
|
|
|
return be.SupportsTagsF()
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2019-08-12 09:12:17 +00:00
|
|
|
func (be *MockBackend) SupportsOrganizations() bool {
|
|
|
|
if be.SupportsOrganizationsF != nil {
|
|
|
|
return be.SupportsOrganizationsF()
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2023-10-27 07:33:07 +00:00
|
|
|
func (be *MockBackend) SupportsProgress() bool {
|
|
|
|
if be.SupportsProgressF != nil {
|
|
|
|
return be.SupportsProgressF()
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2024-06-13 19:49:49 +00:00
|
|
|
func (be *MockBackend) SupportsDeployments() bool {
|
|
|
|
if be.SupportsOrganizationsF != nil {
|
|
|
|
return be.SupportsDeploymentsF()
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2019-08-12 09:12:17 +00:00
|
|
|
func (be *MockBackend) ParseStackReference(s string) (StackReference, error) {
|
|
|
|
if be.ParseStackReferenceF != nil {
|
|
|
|
return be.ParseStackReferenceF(s)
|
|
|
|
}
|
2023-06-26 22:04:24 +00:00
|
|
|
|
|
|
|
// default implementation
|
|
|
|
split := strings.Split(s, "/")
|
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
|
|
|
var project, name string
|
2023-06-26 22:04:24 +00:00
|
|
|
switch len(split) {
|
|
|
|
case 1:
|
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
|
|
|
name = split[0]
|
2023-06-26 22:04:24 +00:00
|
|
|
case 2:
|
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
|
|
|
project = split[0]
|
|
|
|
name = split[1]
|
2023-06-26 22:04:24 +00:00
|
|
|
case 3:
|
|
|
|
// org is unused
|
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
|
|
|
project = split[1]
|
|
|
|
name = split[2]
|
|
|
|
}
|
|
|
|
|
|
|
|
parsedName, err := tokens.ParseStackName(name)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2023-06-26 22:04:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return &MockStackReference{
|
|
|
|
StringV: s,
|
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
|
|
|
NameV: parsedName,
|
|
|
|
ProjectV: tokens.Name(project),
|
2023-06-26 22:04:24 +00:00
|
|
|
FullyQualifiedNameV: tokens.QName(s),
|
|
|
|
}, nil
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
|
2019-12-30 18:24:48 +00:00
|
|
|
func (be *MockBackend) ValidateStackName(s string) error {
|
|
|
|
if be.ValidateStackNameF != nil {
|
|
|
|
return be.ValidateStackNameF(s)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2023-06-21 15:46:54 +00:00
|
|
|
func (be *MockBackend) DoesProjectExist(ctx context.Context, orgName string, projectName string) (bool, error) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if be.DoesProjectExistF != nil {
|
2023-06-21 15:46:54 +00:00
|
|
|
return be.DoesProjectExistF(ctx, orgName, projectName)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (be *MockBackend) GetStack(ctx context.Context, stackRef StackReference) (Stack, error) {
|
|
|
|
if be.GetStackF != nil {
|
|
|
|
return be.GetStackF(ctx, stackRef)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2023-02-17 15:44:43 +00:00
|
|
|
func (be *MockBackend) CreateStack(ctx context.Context, stackRef StackReference,
|
2023-03-20 21:12:17 +00:00
|
|
|
root string, opts *CreateStackOptions,
|
2023-03-03 16:36:39 +00:00
|
|
|
) (Stack, error) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if be.CreateStackF != nil {
|
2023-03-03 20:32:42 +00:00
|
|
|
return be.CreateStackF(ctx, stackRef, root, opts)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2019-10-14 21:30:42 +00:00
|
|
|
func (be *MockBackend) RemoveStack(ctx context.Context, stack Stack, force bool) (bool, error) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if be.RemoveStackF != nil {
|
2019-10-14 21:30:42 +00:00
|
|
|
return be.RemoveStackF(ctx, stack, force)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2021-07-29 20:37:17 +00:00
|
|
|
func (be *MockBackend) ListStacks(ctx context.Context, filter ListStacksFilter, inContToken ContinuationToken) (
|
2023-03-03 16:36:39 +00:00
|
|
|
[]StackSummary, ContinuationToken, error,
|
|
|
|
) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if be.ListStacksF != nil {
|
2021-07-29 20:37:17 +00:00
|
|
|
return be.ListStacksF(ctx, filter, inContToken)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
Correctly rename stack files during a rename (#5812)
* Correctly rename stack files during a rename
This fixes pulumi/pulumi#4463, by renaming a stack's configuration
file based on its stack-part, and ignoring the owner-part. Our
workspace system doesn't recognize configuration files with fully
qualified names. That, by the way, causes problems if we have
multiple stacks in different organizations that share a stack-part.
The fix here is simple: propagate the new StackReference from the
Rename operation and rely on the backend's normalization to a
simple name, and then use that the same way we are using a
StackReference to determine the path for the origin stack.
An alternative fix is to recognize fully qualified config files,
however, there's a fair bit of cleanup we will be doing as part of
https://github.com/pulumi/pulumi/issues/2522 and
https://github.com/pulumi/pulumi/issues/4605, so figured it is best
to make this work the way the system expects first, and revisit it
as part of those overall workstreams. I also suspect we may want to
consider changing the default behavior here as part of
https://github.com/pulumi/pulumi/issues/5731.
Tests TBD; need some advice on how best to test this since it
only happens with our HTTP state backend -- all integration tests
appear to use the local filestate backend at the moment.
* Add a changelog entry for bug fix
* Add some stack rename tests
* Fix a typo
* Address CR feedback
* Make some logic clearer
Use "parsedName" instead of "qn", add a comment explaining why
we're doing this, and also explicitly ignore the error rather
than implicitly doing so with _.
2020-12-02 00:55:48 +00:00
|
|
|
func (be *MockBackend) RenameStack(ctx context.Context, stack Stack,
|
2023-03-03 16:36:39 +00:00
|
|
|
newName tokens.QName,
|
|
|
|
) (StackReference, error) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if be.RenameStackF != nil {
|
2019-10-14 21:30:42 +00:00
|
|
|
return be.RenameStackF(ctx, stack, newName)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (be *MockBackend) GetStackCrypter(stackRef StackReference) (config.Crypter, error) {
|
|
|
|
if be.GetStackCrypterF != nil {
|
|
|
|
return be.GetStackCrypterF(stackRef)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2019-10-14 21:30:42 +00:00
|
|
|
func (be *MockBackend) Preview(ctx context.Context, stack Stack,
|
2023-12-05 08:32:40 +00:00
|
|
|
op UpdateOperation, events chan<- engine.Event,
|
2023-03-03 16:36:39 +00:00
|
|
|
) (*deploy.Plan, sdkDisplay.ResourceChanges, result.Result) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if be.PreviewF != nil {
|
2019-10-14 21:30:42 +00:00
|
|
|
return be.PreviewF(ctx, stack, op)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2019-10-14 21:30:42 +00:00
|
|
|
func (be *MockBackend) Update(ctx context.Context, stack Stack,
|
2023-03-03 16:36:39 +00:00
|
|
|
op UpdateOperation,
|
|
|
|
) (sdkDisplay.ResourceChanges, result.Result) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if be.UpdateF != nil {
|
2019-10-14 21:30:42 +00:00
|
|
|
return be.UpdateF(ctx, stack, op)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2020-10-14 11:51:53 +00:00
|
|
|
func (be *MockBackend) Import(ctx context.Context, stack Stack,
|
2023-03-03 16:36:39 +00:00
|
|
|
op UpdateOperation, imports []deploy.Import,
|
|
|
|
) (sdkDisplay.ResourceChanges, result.Result) {
|
2020-10-14 11:51:53 +00:00
|
|
|
if be.ImportF != nil {
|
|
|
|
return be.ImportF(ctx, stack, op, imports)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2019-10-14 21:30:42 +00:00
|
|
|
func (be *MockBackend) Refresh(ctx context.Context, stack Stack,
|
2023-03-03 16:36:39 +00:00
|
|
|
op UpdateOperation,
|
|
|
|
) (sdkDisplay.ResourceChanges, result.Result) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if be.RefreshF != nil {
|
2019-10-14 21:30:42 +00:00
|
|
|
return be.RefreshF(ctx, stack, op)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2019-10-14 21:30:42 +00:00
|
|
|
func (be *MockBackend) Destroy(ctx context.Context, stack Stack,
|
2023-03-03 16:36:39 +00:00
|
|
|
op UpdateOperation,
|
|
|
|
) (sdkDisplay.ResourceChanges, result.Result) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if be.DestroyF != nil {
|
2019-10-14 21:30:42 +00:00
|
|
|
return be.DestroyF(ctx, stack, op)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2019-11-06 20:56:29 +00:00
|
|
|
func (be *MockBackend) Watch(ctx context.Context, stack Stack,
|
2023-03-03 16:36:39 +00:00
|
|
|
op UpdateOperation, paths []string,
|
|
|
|
) result.Result {
|
2019-11-06 20:56:29 +00:00
|
|
|
if be.WatchF != nil {
|
2021-06-21 07:34:21 +00:00
|
|
|
return be.WatchF(ctx, stack, op, paths)
|
2019-11-06 20:56:29 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2023-09-20 15:43:46 +00:00
|
|
|
func (be *MockBackend) Query(ctx context.Context, op QueryOperation) error {
|
2019-08-12 09:12:17 +00:00
|
|
|
if be.QueryF != nil {
|
2019-08-12 07:22:42 +00:00
|
|
|
return be.QueryF(ctx, op)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2021-02-10 00:20:01 +00:00
|
|
|
func (be *MockBackend) GetHistory(ctx context.Context,
|
|
|
|
stackRef StackReference,
|
|
|
|
pageSize int,
|
2023-03-03 16:36:39 +00:00
|
|
|
page int,
|
|
|
|
) ([]UpdateInfo, error) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if be.GetHistoryF != nil {
|
2021-02-10 00:20:01 +00:00
|
|
|
return be.GetHistoryF(ctx, stackRef, pageSize, page)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2023-01-11 16:04:14 +00:00
|
|
|
func (be *MockBackend) GetLogs(
|
|
|
|
ctx context.Context, secretsProvider secrets.Provider, stack Stack,
|
2023-03-03 16:36:39 +00:00
|
|
|
cfg StackConfiguration, query operations.LogQuery,
|
|
|
|
) ([]operations.LogEntry, error) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if be.GetLogsF != nil {
|
2023-01-11 16:04:14 +00:00
|
|
|
return be.GetLogsF(ctx, secretsProvider, stack, cfg, query)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (be *MockBackend) GetLatestConfiguration(ctx context.Context,
|
2023-03-03 16:36:39 +00:00
|
|
|
stack Stack,
|
|
|
|
) (config.Map, error) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if be.GetLatestConfigurationF != nil {
|
2019-10-14 21:30:42 +00:00
|
|
|
return be.GetLatestConfigurationF(ctx, stack)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2019-10-14 21:30:42 +00:00
|
|
|
func (be *MockBackend) UpdateStackTags(ctx context.Context, stack Stack,
|
2023-03-03 16:36:39 +00:00
|
|
|
tags map[apitype.StackTagName]string,
|
|
|
|
) error {
|
2019-08-12 09:12:17 +00:00
|
|
|
if be.UpdateStackTagsF != nil {
|
2019-10-14 21:30:42 +00:00
|
|
|
return be.UpdateStackTagsF(ctx, stack, tags)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (be *MockBackend) ExportDeployment(ctx context.Context,
|
2023-03-03 16:36:39 +00:00
|
|
|
stack Stack,
|
|
|
|
) (*apitype.UntypedDeployment, error) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if be.ExportDeploymentF != nil {
|
2019-10-14 21:30:42 +00:00
|
|
|
return be.ExportDeploymentF(ctx, stack)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2019-10-14 21:30:42 +00:00
|
|
|
func (be *MockBackend) ImportDeployment(ctx context.Context, stack Stack,
|
2023-03-03 16:36:39 +00:00
|
|
|
deployment *apitype.UntypedDeployment,
|
|
|
|
) error {
|
2019-08-12 09:12:17 +00:00
|
|
|
if be.ImportDeploymentF != nil {
|
2019-10-14 21:30:42 +00:00
|
|
|
return be.ImportDeploymentF(ctx, stack, deployment)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2023-09-23 12:46:11 +00:00
|
|
|
func (be *MockBackend) CurrentUser() (string, []string, *workspace.TokenInformation, error) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if be.CurrentUserF != nil {
|
2023-09-23 12:46:11 +00:00
|
|
|
user, org, tokenInfo, err := be.CurrentUserF()
|
|
|
|
return user, org, tokenInfo, err
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2022-03-03 17:07:05 +00:00
|
|
|
func (be *MockBackend) CancelCurrentUpdate(ctx context.Context, stackRef StackReference) error {
|
|
|
|
if be.CancelCurrentUpdateF != nil {
|
|
|
|
return be.CancelCurrentUpdateF(ctx, stackRef)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2024-06-13 19:49:49 +00:00
|
|
|
func (be *MockBackend) EncryptStackDeploymentSettingsSecret(
|
|
|
|
ctx context.Context, stack Stack, secret string,
|
|
|
|
) (string, error) {
|
|
|
|
if be.EncryptStackDeploymentSettingsSecretF != nil {
|
|
|
|
return be.EncryptStackDeploymentSettingsSecretF(ctx, stack, secret)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (be *MockBackend) UpdateStackDeploymentSettings(ctx context.Context, stack Stack,
|
|
|
|
deployment apitype.DeploymentSettings,
|
|
|
|
) error {
|
|
|
|
if be.UpdateStackDeploymentSettingsF != nil {
|
|
|
|
return be.UpdateStackDeploymentSettingsF(ctx, stack, deployment)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (be *MockBackend) GetStackDeploymentSettings(ctx context.Context,
|
|
|
|
stack Stack,
|
|
|
|
) (*apitype.DeploymentSettings, error) {
|
|
|
|
if be.GetStackDeploymentSettingsF != nil {
|
|
|
|
return be.GetStackDeploymentSettingsF(ctx, stack)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (be *MockBackend) DestroyStackDeploymentSettings(ctx context.Context, stack Stack) error {
|
|
|
|
if be.DestroyStackDeploymentSettingsF != nil {
|
|
|
|
return be.DestroyStackDeploymentSettingsF(ctx, stack)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2023-11-21 10:44:45 +00:00
|
|
|
var _ = EnvironmentsBackend((*MockEnvironmentsBackend)(nil))
|
|
|
|
|
2023-10-10 01:35:39 +00:00
|
|
|
type MockEnvironmentsBackend struct {
|
|
|
|
MockBackend
|
|
|
|
|
2023-11-22 20:57:02 +00:00
|
|
|
CreateEnvironmentF func(
|
|
|
|
ctx context.Context,
|
|
|
|
org string,
|
|
|
|
name string,
|
|
|
|
yaml []byte,
|
|
|
|
) (apitype.EnvironmentDiagnostics, error)
|
|
|
|
|
2023-11-21 10:44:45 +00:00
|
|
|
CheckYAMLEnvironmentF func(
|
|
|
|
ctx context.Context,
|
|
|
|
org string,
|
|
|
|
yaml []byte,
|
|
|
|
) (*esc.Environment, apitype.EnvironmentDiagnostics, error)
|
|
|
|
|
2023-10-10 01:35:39 +00:00
|
|
|
OpenYAMLEnvironmentF func(
|
|
|
|
ctx context.Context,
|
|
|
|
org string,
|
|
|
|
yaml []byte,
|
|
|
|
duration time.Duration,
|
2023-11-21 10:44:45 +00:00
|
|
|
) (*esc.Environment, apitype.EnvironmentDiagnostics, error)
|
|
|
|
}
|
|
|
|
|
2023-11-22 20:57:02 +00:00
|
|
|
func (be *MockEnvironmentsBackend) CreateEnvironment(
|
|
|
|
ctx context.Context,
|
|
|
|
org string,
|
|
|
|
name string,
|
|
|
|
yaml []byte,
|
|
|
|
) (apitype.EnvironmentDiagnostics, error) {
|
|
|
|
if be.CreateEnvironmentF != nil {
|
|
|
|
return be.CreateEnvironmentF(ctx, org, name, yaml)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2023-11-21 10:44:45 +00:00
|
|
|
func (be *MockEnvironmentsBackend) CheckYAMLEnvironment(
|
|
|
|
ctx context.Context,
|
|
|
|
org string,
|
|
|
|
yaml []byte,
|
|
|
|
) (*esc.Environment, apitype.EnvironmentDiagnostics, error) {
|
|
|
|
if be.CheckYAMLEnvironmentF != nil {
|
|
|
|
return be.CheckYAMLEnvironmentF(ctx, org, yaml)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
2023-10-10 01:35:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (be *MockEnvironmentsBackend) OpenYAMLEnvironment(
|
|
|
|
ctx context.Context,
|
|
|
|
org string,
|
|
|
|
yaml []byte,
|
|
|
|
duration time.Duration,
|
2023-11-21 10:44:45 +00:00
|
|
|
) (*esc.Environment, apitype.EnvironmentDiagnostics, error) {
|
2023-10-10 01:35:39 +00:00
|
|
|
if be.OpenYAMLEnvironmentF != nil {
|
|
|
|
return be.OpenYAMLEnvironmentF(ctx, org, yaml, duration)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2019-08-12 09:12:17 +00:00
|
|
|
//
|
|
|
|
// Mock stack.
|
|
|
|
//
|
|
|
|
|
|
|
|
type MockStack struct {
|
|
|
|
RefF func() StackReference
|
2023-10-10 01:35:39 +00:00
|
|
|
OrgNameF func() string
|
2019-08-12 09:12:17 +00:00
|
|
|
ConfigF func() config.Map
|
2023-01-11 16:04:14 +00:00
|
|
|
SnapshotF func(ctx context.Context, secretsProvider secrets.Provider) (*deploy.Snapshot, error)
|
2022-03-23 22:05:26 +00:00
|
|
|
TagsF func() map[apitype.StackTagName]string
|
2019-08-12 09:12:17 +00:00
|
|
|
BackendF func() Backend
|
2022-06-27 14:08:06 +00:00
|
|
|
PreviewF func(ctx context.Context, op UpdateOperation) (*deploy.Plan, sdkDisplay.ResourceChanges, result.Result)
|
|
|
|
UpdateF func(ctx context.Context, op UpdateOperation) (sdkDisplay.ResourceChanges, result.Result)
|
2020-10-14 11:51:53 +00:00
|
|
|
ImportF func(ctx context.Context, op UpdateOperation,
|
2022-06-27 14:08:06 +00:00
|
|
|
imports []deploy.Import) (sdkDisplay.ResourceChanges, result.Result)
|
|
|
|
RefreshF func(ctx context.Context, op UpdateOperation) (sdkDisplay.ResourceChanges, result.Result)
|
|
|
|
DestroyF func(ctx context.Context, op UpdateOperation) (sdkDisplay.ResourceChanges, result.Result)
|
2021-06-21 07:34:21 +00:00
|
|
|
WatchF func(ctx context.Context, op UpdateOperation, paths []string) result.Result
|
2020-10-14 11:51:53 +00:00
|
|
|
QueryF func(ctx context.Context, op UpdateOperation) result.Result
|
|
|
|
RemoveF func(ctx context.Context, force bool) (bool, error)
|
Correctly rename stack files during a rename (#5812)
* Correctly rename stack files during a rename
This fixes pulumi/pulumi#4463, by renaming a stack's configuration
file based on its stack-part, and ignoring the owner-part. Our
workspace system doesn't recognize configuration files with fully
qualified names. That, by the way, causes problems if we have
multiple stacks in different organizations that share a stack-part.
The fix here is simple: propagate the new StackReference from the
Rename operation and rely on the backend's normalization to a
simple name, and then use that the same way we are using a
StackReference to determine the path for the origin stack.
An alternative fix is to recognize fully qualified config files,
however, there's a fair bit of cleanup we will be doing as part of
https://github.com/pulumi/pulumi/issues/2522 and
https://github.com/pulumi/pulumi/issues/4605, so figured it is best
to make this work the way the system expects first, and revisit it
as part of those overall workstreams. I also suspect we may want to
consider changing the default behavior here as part of
https://github.com/pulumi/pulumi/issues/5731.
Tests TBD; need some advice on how best to test this since it
only happens with our HTTP state backend -- all integration tests
appear to use the local filestate backend at the moment.
* Add a changelog entry for bug fix
* Add some stack rename tests
* Fix a typo
* Address CR feedback
* Make some logic clearer
Use "parsedName" instead of "qn", add a comment explaining why
we're doing this, and also explicitly ignore the error rather
than implicitly doing so with _.
2020-12-02 00:55:48 +00:00
|
|
|
RenameF func(ctx context.Context, newName tokens.QName) (StackReference, error)
|
2023-01-11 16:04:14 +00:00
|
|
|
GetLogsF func(ctx context.Context, secretsProvider secrets.Provider, cfg StackConfiguration,
|
2019-08-12 09:12:17 +00:00
|
|
|
query operations.LogQuery) ([]operations.LogEntry, error)
|
2022-08-18 14:31:34 +00:00
|
|
|
ExportDeploymentF func(ctx context.Context) (*apitype.UntypedDeployment, error)
|
|
|
|
ImportDeploymentF func(ctx context.Context, deployment *apitype.UntypedDeployment) error
|
2023-01-12 15:33:17 +00:00
|
|
|
DefaultSecretManagerF func(info *workspace.ProjectStack) (secrets.Manager, error)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var _ Stack = (*MockStack)(nil)
|
|
|
|
|
|
|
|
func (ms *MockStack) Ref() StackReference {
|
|
|
|
if ms.RefF != nil {
|
|
|
|
return ms.RefF()
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2023-10-10 01:35:39 +00:00
|
|
|
func (ms *MockStack) OrgName() string {
|
|
|
|
if ms.OrgNameF != nil {
|
|
|
|
return ms.OrgNameF()
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2019-08-12 09:12:17 +00:00
|
|
|
func (ms *MockStack) Config() config.Map {
|
|
|
|
if ms.ConfigF != nil {
|
|
|
|
return ms.ConfigF()
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2023-01-11 16:04:14 +00:00
|
|
|
func (ms *MockStack) Snapshot(ctx context.Context, secretsProvider secrets.Provider) (*deploy.Snapshot, error) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if ms.SnapshotF != nil {
|
2023-01-11 16:04:14 +00:00
|
|
|
return ms.SnapshotF(ctx, secretsProvider)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2022-03-23 22:05:26 +00:00
|
|
|
func (ms *MockStack) Tags() map[apitype.StackTagName]string {
|
|
|
|
if ms.TagsF != nil {
|
|
|
|
return ms.TagsF()
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2019-08-12 09:12:17 +00:00
|
|
|
func (ms *MockStack) Backend() Backend {
|
|
|
|
if ms.BackendF != nil {
|
|
|
|
return ms.BackendF()
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2022-01-31 10:31:51 +00:00
|
|
|
func (ms *MockStack) Preview(
|
|
|
|
ctx context.Context,
|
2023-12-05 08:32:40 +00:00
|
|
|
op UpdateOperation, events chan<- engine.Event,
|
2023-03-03 16:36:39 +00:00
|
|
|
) (*deploy.Plan, sdkDisplay.ResourceChanges, result.Result) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if ms.PreviewF != nil {
|
|
|
|
return ms.PreviewF(ctx, op)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2022-06-27 14:08:06 +00:00
|
|
|
func (ms *MockStack) Update(ctx context.Context, op UpdateOperation) (sdkDisplay.ResourceChanges, result.Result) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if ms.UpdateF != nil {
|
|
|
|
return ms.UpdateF(ctx, op)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2020-10-14 11:51:53 +00:00
|
|
|
func (ms *MockStack) Import(ctx context.Context, op UpdateOperation,
|
2023-03-03 16:36:39 +00:00
|
|
|
imports []deploy.Import,
|
|
|
|
) (sdkDisplay.ResourceChanges, result.Result) {
|
2020-10-14 11:51:53 +00:00
|
|
|
if ms.ImportF != nil {
|
|
|
|
return ms.ImportF(ctx, op, imports)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2022-06-27 14:08:06 +00:00
|
|
|
func (ms *MockStack) Refresh(ctx context.Context, op UpdateOperation) (sdkDisplay.ResourceChanges, result.Result) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if ms.RefreshF != nil {
|
|
|
|
return ms.RefreshF(ctx, op)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2022-06-27 14:08:06 +00:00
|
|
|
func (ms *MockStack) Destroy(ctx context.Context, op UpdateOperation) (sdkDisplay.ResourceChanges, result.Result) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if ms.DestroyF != nil {
|
|
|
|
return ms.DestroyF(ctx, op)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2021-06-21 07:34:21 +00:00
|
|
|
func (ms *MockStack) Watch(ctx context.Context, op UpdateOperation, paths []string) result.Result {
|
2019-11-06 20:56:29 +00:00
|
|
|
if ms.WatchF != nil {
|
2021-06-21 07:34:21 +00:00
|
|
|
return ms.WatchF(ctx, op, paths)
|
2019-11-06 20:56:29 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2019-08-12 09:12:17 +00:00
|
|
|
func (ms *MockStack) Query(ctx context.Context, op UpdateOperation) result.Result {
|
|
|
|
if ms.QueryF != nil {
|
|
|
|
return ms.QueryF(ctx, op)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ms *MockStack) Remove(ctx context.Context, force bool) (bool, error) {
|
|
|
|
if ms.RemoveF != nil {
|
|
|
|
return ms.RemoveF(ctx, force)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
Correctly rename stack files during a rename (#5812)
* Correctly rename stack files during a rename
This fixes pulumi/pulumi#4463, by renaming a stack's configuration
file based on its stack-part, and ignoring the owner-part. Our
workspace system doesn't recognize configuration files with fully
qualified names. That, by the way, causes problems if we have
multiple stacks in different organizations that share a stack-part.
The fix here is simple: propagate the new StackReference from the
Rename operation and rely on the backend's normalization to a
simple name, and then use that the same way we are using a
StackReference to determine the path for the origin stack.
An alternative fix is to recognize fully qualified config files,
however, there's a fair bit of cleanup we will be doing as part of
https://github.com/pulumi/pulumi/issues/2522 and
https://github.com/pulumi/pulumi/issues/4605, so figured it is best
to make this work the way the system expects first, and revisit it
as part of those overall workstreams. I also suspect we may want to
consider changing the default behavior here as part of
https://github.com/pulumi/pulumi/issues/5731.
Tests TBD; need some advice on how best to test this since it
only happens with our HTTP state backend -- all integration tests
appear to use the local filestate backend at the moment.
* Add a changelog entry for bug fix
* Add some stack rename tests
* Fix a typo
* Address CR feedback
* Make some logic clearer
Use "parsedName" instead of "qn", add a comment explaining why
we're doing this, and also explicitly ignore the error rather
than implicitly doing so with _.
2020-12-02 00:55:48 +00:00
|
|
|
func (ms *MockStack) Rename(ctx context.Context, newName tokens.QName) (StackReference, error) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if ms.RenameF != nil {
|
|
|
|
return ms.RenameF(ctx, newName)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2023-01-11 16:04:14 +00:00
|
|
|
func (ms *MockStack) GetLogs(ctx context.Context, secretsProvider secrets.Provider, cfg StackConfiguration,
|
2023-03-03 16:36:39 +00:00
|
|
|
query operations.LogQuery,
|
|
|
|
) ([]operations.LogEntry, error) {
|
2019-08-12 09:12:17 +00:00
|
|
|
if ms.GetLogsF != nil {
|
2023-01-11 16:04:14 +00:00
|
|
|
return ms.GetLogsF(ctx, secretsProvider, cfg, query)
|
2019-08-12 09:12:17 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ms *MockStack) ExportDeployment(ctx context.Context) (*apitype.UntypedDeployment, error) {
|
|
|
|
if ms.ExportDeploymentF != nil {
|
|
|
|
return ms.ExportDeploymentF(ctx)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ms *MockStack) ImportDeployment(ctx context.Context, deployment *apitype.UntypedDeployment) error {
|
|
|
|
if ms.ImportDeploymentF != nil {
|
|
|
|
return ms.ImportDeploymentF(ctx, deployment)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
2022-08-18 14:31:34 +00:00
|
|
|
|
2023-01-12 15:33:17 +00:00
|
|
|
func (ms *MockStack) DefaultSecretManager(info *workspace.ProjectStack) (secrets.Manager, error) {
|
2022-08-18 14:31:34 +00:00
|
|
|
if ms.DefaultSecretManagerF != nil {
|
2023-01-12 15:33:17 +00:00
|
|
|
return ms.DefaultSecretManagerF(info)
|
2022-08-18 14:31:34 +00:00
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
2023-03-24 22:28:51 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// Mock stack reference
|
|
|
|
//
|
|
|
|
|
|
|
|
// MockStackReference is a mock implementation of [StackReference].
|
|
|
|
// Set the fields on this struct to control the behavior of the mock.
|
|
|
|
type MockStackReference struct {
|
|
|
|
StringV string
|
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
|
|
|
NameV tokens.StackName
|
2023-04-27 08:13:08 +00:00
|
|
|
ProjectV tokens.Name
|
2023-03-24 22:28:51 +00:00
|
|
|
FullyQualifiedNameV tokens.QName
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ StackReference = (*MockStackReference)(nil)
|
|
|
|
|
|
|
|
func (r *MockStackReference) String() string {
|
|
|
|
if r.StringV != "" {
|
|
|
|
return r.StringV
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
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
|
|
|
func (r *MockStackReference) Name() tokens.StackName {
|
|
|
|
if !r.NameV.IsEmpty() {
|
2023-03-24 22:28:51 +00:00
|
|
|
return r.NameV
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
2023-04-27 08:13:08 +00:00
|
|
|
func (r *MockStackReference) Project() (tokens.Name, bool) {
|
|
|
|
if r.ProjectV != "" {
|
|
|
|
return r.ProjectV, true
|
|
|
|
}
|
|
|
|
return "", false
|
|
|
|
}
|
|
|
|
|
2023-03-24 22:28:51 +00:00
|
|
|
func (r *MockStackReference) FullyQualifiedName() tokens.QName {
|
|
|
|
if r.FullyQualifiedNameV != "" {
|
|
|
|
return r.FullyQualifiedNameV
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
2023-10-05 16:51:06 +00:00
|
|
|
|
|
|
|
type MockPolicyPack struct {
|
|
|
|
RefF func() PolicyPackReference
|
|
|
|
BackendF func() Backend
|
|
|
|
PublishF func(context.Context, PublishOperation) result.Result
|
|
|
|
EnableF func(context.Context, string, PolicyPackOperation) error
|
|
|
|
DisableF func(context.Context, string, PolicyPackOperation) error
|
|
|
|
ValidateF func(context.Context, PolicyPackOperation) error
|
|
|
|
RemoveF func(context.Context, PolicyPackOperation) error
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ PolicyPack = (*MockPolicyPack)(nil)
|
|
|
|
|
|
|
|
func (mp *MockPolicyPack) Ref() PolicyPackReference {
|
|
|
|
if mp.RefF != nil {
|
|
|
|
return mp.RefF()
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mp *MockPolicyPack) Backend() Backend {
|
|
|
|
if mp.BackendF != nil {
|
|
|
|
return mp.BackendF()
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mp *MockPolicyPack) Publish(ctx context.Context, op PublishOperation) result.Result {
|
|
|
|
if mp.PublishF != nil {
|
|
|
|
return mp.PublishF(ctx, op)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mp *MockPolicyPack) Enable(ctx context.Context, orgName string, op PolicyPackOperation) error {
|
|
|
|
if mp.EnableF != nil {
|
|
|
|
return mp.EnableF(ctx, orgName, op)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mp *MockPolicyPack) Disable(ctx context.Context, orgName string, op PolicyPackOperation) error {
|
|
|
|
if mp.DisableF != nil {
|
|
|
|
return mp.DisableF(ctx, orgName, op)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mp *MockPolicyPack) Validate(ctx context.Context, op PolicyPackOperation) error {
|
|
|
|
if mp.ValidateF != nil {
|
|
|
|
return mp.ValidateF(ctx, op)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mp *MockPolicyPack) Remove(ctx context.Context, op PolicyPackOperation) error {
|
|
|
|
if mp.RemoveF != nil {
|
|
|
|
return mp.RemoveF(ctx, op)
|
|
|
|
}
|
|
|
|
panic("not implemented")
|
|
|
|
}
|