2018-03-21 20:43:21 +01:00
|
|
|
// Copyright 2016-2018, Pulumi Corporation. All rights reserved.
|
Make some updates based on CR feedback
This change implements some feedback from @ellismg.
* Make backend.Stack an interface and let backends implement it,
enabling dynamic type testing/casting to access information
specific to that backend. For instance, the cloud.Stack conveys
the cloud URL, org name, and PPC name, for each stack.
* Similarly expose specialized backend.Backend interfaces,
local.Backend and cloud.Backend, to convey specific information.
* Redo a bunch of the commands in terms of these.
* Keeping with this theme, turn the CreateStack options into an
opaque interface{}, and let the specific backends expose their
own structures with their own settings (like PPC name in cloud).
* Show both the org and PPC names in the cloud column printed in
the stack ls command, in addition to the Pulumi Cloud URL.
Unrelated, but useful:
* Special case the 401 HTTP response and make a friendly error,
to tell the developer they must use `pulumi login`. This is
better than tossing raw "401: Unauthorized" errors in their face.
* Change the "Updating stack '..' in the Pulumi Cloud" message to
use the correct action verb ("Previewing", "Destroying", etc).
2017-12-03 16:51:18 +01:00
|
|
|
|
|
|
|
package cloud
|
|
|
|
|
|
|
|
import (
|
2018-04-18 12:19:13 +02:00
|
|
|
"fmt"
|
|
|
|
|
2018-04-20 08:54:33 +02:00
|
|
|
"github.com/pkg/errors"
|
2018-01-11 00:04:55 +01:00
|
|
|
"github.com/pulumi/pulumi/pkg/apitype"
|
Make some updates based on CR feedback
This change implements some feedback from @ellismg.
* Make backend.Stack an interface and let backends implement it,
enabling dynamic type testing/casting to access information
specific to that backend. For instance, the cloud.Stack conveys
the cloud URL, org name, and PPC name, for each stack.
* Similarly expose specialized backend.Backend interfaces,
local.Backend and cloud.Backend, to convey specific information.
* Redo a bunch of the commands in terms of these.
* Keeping with this theme, turn the CreateStack options into an
opaque interface{}, and let the specific backends expose their
own structures with their own settings (like PPC name in cloud).
* Show both the org and PPC names in the cloud column printed in
the stack ls command, in addition to the Pulumi Cloud URL.
Unrelated, but useful:
* Special case the 401 HTTP response and make a friendly error,
to tell the developer they must use `pulumi login`. This is
better than tossing raw "401: Unauthorized" errors in their face.
* Change the "Updating stack '..' in the Pulumi Cloud" message to
use the correct action verb ("Previewing", "Destroying", etc).
2017-12-03 16:51:18 +01:00
|
|
|
"github.com/pulumi/pulumi/pkg/backend"
|
|
|
|
"github.com/pulumi/pulumi/pkg/operations"
|
|
|
|
"github.com/pulumi/pulumi/pkg/resource"
|
|
|
|
"github.com/pulumi/pulumi/pkg/resource/config"
|
|
|
|
"github.com/pulumi/pulumi/pkg/resource/deploy"
|
|
|
|
"github.com/pulumi/pulumi/pkg/tokens"
|
2018-02-14 22:56:16 +01:00
|
|
|
"github.com/pulumi/pulumi/pkg/workspace"
|
Make some updates based on CR feedback
This change implements some feedback from @ellismg.
* Make backend.Stack an interface and let backends implement it,
enabling dynamic type testing/casting to access information
specific to that backend. For instance, the cloud.Stack conveys
the cloud URL, org name, and PPC name, for each stack.
* Similarly expose specialized backend.Backend interfaces,
local.Backend and cloud.Backend, to convey specific information.
* Redo a bunch of the commands in terms of these.
* Keeping with this theme, turn the CreateStack options into an
opaque interface{}, and let the specific backends expose their
own structures with their own settings (like PPC name in cloud).
* Show both the org and PPC names in the cloud column printed in
the stack ls command, in addition to the Pulumi Cloud URL.
Unrelated, but useful:
* Special case the 401 HTTP response and make a friendly error,
to tell the developer they must use `pulumi login`. This is
better than tossing raw "401: Unauthorized" errors in their face.
* Change the "Updating stack '..' in the Pulumi Cloud" message to
use the correct action verb ("Previewing", "Destroying", etc).
2017-12-03 16:51:18 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// Stack is a cloud stack. This simply adds some cloud-specific properties atop the standard backend stack interface.
|
|
|
|
type Stack interface {
|
|
|
|
backend.Stack
|
2018-04-20 08:54:33 +02:00
|
|
|
CloudURL() string // the URL to the cloud containing this stack.
|
|
|
|
OrgName() string // the organization that owns this stack.
|
|
|
|
CloudName() string // the PPC in which this stack is running.
|
|
|
|
RunLocally() bool // true if previews/updates/destroys targeting this stack run locally.
|
|
|
|
ConsoleURL() (string, error) // the URL to view the stack's information on Pulumi.com
|
Make some updates based on CR feedback
This change implements some feedback from @ellismg.
* Make backend.Stack an interface and let backends implement it,
enabling dynamic type testing/casting to access information
specific to that backend. For instance, the cloud.Stack conveys
the cloud URL, org name, and PPC name, for each stack.
* Similarly expose specialized backend.Backend interfaces,
local.Backend and cloud.Backend, to convey specific information.
* Redo a bunch of the commands in terms of these.
* Keeping with this theme, turn the CreateStack options into an
opaque interface{}, and let the specific backends expose their
own structures with their own settings (like PPC name in cloud).
* Show both the org and PPC names in the cloud column printed in
the stack ls command, in addition to the Pulumi Cloud URL.
Unrelated, but useful:
* Special case the 401 HTTP response and make a friendly error,
to tell the developer they must use `pulumi login`. This is
better than tossing raw "401: Unauthorized" errors in their face.
* Change the "Updating stack '..' in the Pulumi Cloud" message to
use the correct action verb ("Previewing", "Destroying", etc).
2017-12-03 16:51:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// cloudStack is a cloud stack descriptor.
|
|
|
|
type cloudStack struct {
|
2018-04-18 01:37:52 +02:00
|
|
|
name backend.StackReference // the stack's name.
|
|
|
|
cloudURL string // the URL to the cloud containing this stack.
|
|
|
|
orgName string // the organization that owns this stack.
|
|
|
|
cloudName string // the PPC in which this stack is running.
|
|
|
|
config config.Map // the stack's config bag.
|
|
|
|
snapshot *deploy.Snapshot // a snapshot representing the latest deployment state.
|
|
|
|
b *cloudBackend // a pointer to the backend this stack belongs to.
|
|
|
|
}
|
|
|
|
|
|
|
|
type cloudBackendReference struct {
|
2018-04-18 12:19:13 +02:00
|
|
|
name tokens.QName
|
|
|
|
owner string
|
|
|
|
b *cloudBackend
|
2018-04-18 01:37:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c cloudBackendReference) String() string {
|
2018-04-18 20:25:16 +02:00
|
|
|
curUser, err := c.b.client.GetPulumiAccountName()
|
2018-04-18 12:19:13 +02:00
|
|
|
if err != nil {
|
|
|
|
curUser = ""
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.owner == curUser {
|
|
|
|
return string(c.name)
|
|
|
|
}
|
|
|
|
|
|
|
|
return fmt.Sprintf("%s/%s", c.owner, c.name)
|
2018-04-18 01:37:52 +02:00
|
|
|
}
|
|
|
|
|
2018-04-18 20:25:16 +02:00
|
|
|
func (c cloudBackendReference) StackName() tokens.QName {
|
2018-04-18 01:37:52 +02:00
|
|
|
return c.name
|
Make some updates based on CR feedback
This change implements some feedback from @ellismg.
* Make backend.Stack an interface and let backends implement it,
enabling dynamic type testing/casting to access information
specific to that backend. For instance, the cloud.Stack conveys
the cloud URL, org name, and PPC name, for each stack.
* Similarly expose specialized backend.Backend interfaces,
local.Backend and cloud.Backend, to convey specific information.
* Redo a bunch of the commands in terms of these.
* Keeping with this theme, turn the CreateStack options into an
opaque interface{}, and let the specific backends expose their
own structures with their own settings (like PPC name in cloud).
* Show both the org and PPC names in the cloud column printed in
the stack ls command, in addition to the Pulumi Cloud URL.
Unrelated, but useful:
* Special case the 401 HTTP response and make a friendly error,
to tell the developer they must use `pulumi login`. This is
better than tossing raw "401: Unauthorized" errors in their face.
* Change the "Updating stack '..' in the Pulumi Cloud" message to
use the correct action verb ("Previewing", "Destroying", etc).
2017-12-03 16:51:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func newStack(apistack apitype.Stack, b *cloudBackend) Stack {
|
|
|
|
// Create a fake snapshot out of this stack.
|
|
|
|
// TODO[pulumi/pulumi-service#249]: add time, version, etc. info to the manifest.
|
|
|
|
stackName := apistack.StackName
|
2018-02-22 00:11:21 +01:00
|
|
|
|
Make some updates based on CR feedback
This change implements some feedback from @ellismg.
* Make backend.Stack an interface and let backends implement it,
enabling dynamic type testing/casting to access information
specific to that backend. For instance, the cloud.Stack conveys
the cloud URL, org name, and PPC name, for each stack.
* Similarly expose specialized backend.Backend interfaces,
local.Backend and cloud.Backend, to convey specific information.
* Redo a bunch of the commands in terms of these.
* Keeping with this theme, turn the CreateStack options into an
opaque interface{}, and let the specific backends expose their
own structures with their own settings (like PPC name in cloud).
* Show both the org and PPC names in the cloud column printed in
the stack ls command, in addition to the Pulumi Cloud URL.
Unrelated, but useful:
* Special case the 401 HTTP response and make a friendly error,
to tell the developer they must use `pulumi login`. This is
better than tossing raw "401: Unauthorized" errors in their face.
* Change the "Updating stack '..' in the Pulumi Cloud" message to
use the correct action verb ("Previewing", "Destroying", etc).
2017-12-03 16:51:18 +01:00
|
|
|
var resources []*resource.State
|
|
|
|
for _, res := range apistack.Resources {
|
|
|
|
resources = append(resources, resource.NewState(
|
2018-02-28 19:02:02 +01:00
|
|
|
res.Type,
|
|
|
|
res.URN,
|
Make some updates based on CR feedback
This change implements some feedback from @ellismg.
* Make backend.Stack an interface and let backends implement it,
enabling dynamic type testing/casting to access information
specific to that backend. For instance, the cloud.Stack conveys
the cloud URL, org name, and PPC name, for each stack.
* Similarly expose specialized backend.Backend interfaces,
local.Backend and cloud.Backend, to convey specific information.
* Redo a bunch of the commands in terms of these.
* Keeping with this theme, turn the CreateStack options into an
opaque interface{}, and let the specific backends expose their
own structures with their own settings (like PPC name in cloud).
* Show both the org and PPC names in the cloud column printed in
the stack ls command, in addition to the Pulumi Cloud URL.
Unrelated, but useful:
* Special case the 401 HTTP response and make a friendly error,
to tell the developer they must use `pulumi login`. This is
better than tossing raw "401: Unauthorized" errors in their face.
* Change the "Updating stack '..' in the Pulumi Cloud" message to
use the correct action verb ("Previewing", "Destroying", etc).
2017-12-03 16:51:18 +01:00
|
|
|
res.Custom,
|
|
|
|
false,
|
2018-02-28 19:02:02 +01:00
|
|
|
res.ID,
|
Make some updates based on CR feedback
This change implements some feedback from @ellismg.
* Make backend.Stack an interface and let backends implement it,
enabling dynamic type testing/casting to access information
specific to that backend. For instance, the cloud.Stack conveys
the cloud URL, org name, and PPC name, for each stack.
* Similarly expose specialized backend.Backend interfaces,
local.Backend and cloud.Backend, to convey specific information.
* Redo a bunch of the commands in terms of these.
* Keeping with this theme, turn the CreateStack options into an
opaque interface{}, and let the specific backends expose their
own structures with their own settings (like PPC name in cloud).
* Show both the org and PPC names in the cloud column printed in
the stack ls command, in addition to the Pulumi Cloud URL.
Unrelated, but useful:
* Special case the 401 HTTP response and make a friendly error,
to tell the developer they must use `pulumi login`. This is
better than tossing raw "401: Unauthorized" errors in their face.
* Change the "Updating stack '..' in the Pulumi Cloud" message to
use the correct action verb ("Previewing", "Destroying", etc).
2017-12-03 16:51:18 +01:00
|
|
|
resource.NewPropertyMapFromMap(res.Inputs),
|
|
|
|
resource.NewPropertyMapFromMap(res.Outputs),
|
2018-02-28 19:02:02 +01:00
|
|
|
res.Parent,
|
Implement resource protection (#751)
This change implements resource protection, as per pulumi/pulumi#689.
The overall idea is that a resource can be marked as "protect: true",
which will prevent deletion of that resource for any reason whatsoever
(straight deletion, replacement, etc). This is expressed in the
program. To "unprotect" a resource, one must perform an update setting
"protect: false", and then afterwards, they can delete the resource.
For example:
let res = new MyResource("precious", { .. }, { protect: true });
Afterwards, the resource will display in the CLI with a lock icon, and
any attempts to remove it will fail in the usual ways (in planning or,
worst case, during an actual update).
This was done by adding a new ResourceOptions bag parameter to the
base Resource types. This is unfortunately a breaking change, but now
is the right time to take this one. We had been adding new settings
one by one -- like parent and dependsOn -- and this new approach will
set us up to add any number of additional settings down the road,
without needing to worry about breaking anything ever again.
This is related to protected stacks, as described in
pulumi/pulumi-service#399. Most likely this will serve as a foundational
building block that enables the coarser grained policy management.
2017-12-20 23:31:07 +01:00
|
|
|
res.Protect,
|
2018-02-22 21:52:50 +01:00
|
|
|
// TODO(swgillespie) provide an actual list of dependencies
|
|
|
|
[]resource.URN{},
|
Make some updates based on CR feedback
This change implements some feedback from @ellismg.
* Make backend.Stack an interface and let backends implement it,
enabling dynamic type testing/casting to access information
specific to that backend. For instance, the cloud.Stack conveys
the cloud URL, org name, and PPC name, for each stack.
* Similarly expose specialized backend.Backend interfaces,
local.Backend and cloud.Backend, to convey specific information.
* Redo a bunch of the commands in terms of these.
* Keeping with this theme, turn the CreateStack options into an
opaque interface{}, and let the specific backends expose their
own structures with their own settings (like PPC name in cloud).
* Show both the org and PPC names in the cloud column printed in
the stack ls command, in addition to the Pulumi Cloud URL.
Unrelated, but useful:
* Special case the 401 HTTP response and make a friendly error,
to tell the developer they must use `pulumi login`. This is
better than tossing raw "401: Unauthorized" errors in their face.
* Change the "Updating stack '..' in the Pulumi Cloud" message to
use the correct action verb ("Previewing", "Destroying", etc).
2017-12-03 16:51:18 +01:00
|
|
|
))
|
|
|
|
}
|
|
|
|
snapshot := deploy.NewSnapshot(stackName, deploy.Manifest{}, resources)
|
|
|
|
|
|
|
|
// Now assemble all the pieces into a stack structure.
|
|
|
|
return &cloudStack{
|
2018-04-18 12:19:13 +02:00
|
|
|
name: cloudBackendReference{
|
|
|
|
owner: apistack.OrgName,
|
|
|
|
name: stackName,
|
|
|
|
b: b,
|
|
|
|
},
|
2018-03-21 18:33:34 +01:00
|
|
|
cloudURL: b.CloudURL(),
|
Make some updates based on CR feedback
This change implements some feedback from @ellismg.
* Make backend.Stack an interface and let backends implement it,
enabling dynamic type testing/casting to access information
specific to that backend. For instance, the cloud.Stack conveys
the cloud URL, org name, and PPC name, for each stack.
* Similarly expose specialized backend.Backend interfaces,
local.Backend and cloud.Backend, to convey specific information.
* Redo a bunch of the commands in terms of these.
* Keeping with this theme, turn the CreateStack options into an
opaque interface{}, and let the specific backends expose their
own structures with their own settings (like PPC name in cloud).
* Show both the org and PPC names in the cloud column printed in
the stack ls command, in addition to the Pulumi Cloud URL.
Unrelated, but useful:
* Special case the 401 HTTP response and make a friendly error,
to tell the developer they must use `pulumi login`. This is
better than tossing raw "401: Unauthorized" errors in their face.
* Change the "Updating stack '..' in the Pulumi Cloud" message to
use the correct action verb ("Previewing", "Destroying", etc).
2017-12-03 16:51:18 +01:00
|
|
|
orgName: apistack.OrgName,
|
|
|
|
cloudName: apistack.CloudName,
|
|
|
|
config: nil, // TODO[pulumi/pulumi-service#249]: add the config variables.
|
|
|
|
snapshot: snapshot,
|
|
|
|
b: b,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-22 18:42:43 +01:00
|
|
|
// managedCloudName is the name used to refer to the cloud in the Pulumi Service that owns all of an organization's
|
|
|
|
// managed stacks. All engine operations for a managed stack--previews, updates, destroys, etc.--run locally.
|
|
|
|
const managedCloudName = "pulumi"
|
|
|
|
|
2018-04-18 01:37:52 +02:00
|
|
|
func (s *cloudStack) Name() backend.StackReference { return s.name }
|
|
|
|
func (s *cloudStack) Config() config.Map { return s.config }
|
|
|
|
func (s *cloudStack) Snapshot() *deploy.Snapshot { return s.snapshot }
|
|
|
|
func (s *cloudStack) Backend() backend.Backend { return s.b }
|
|
|
|
func (s *cloudStack) CloudURL() string { return s.cloudURL }
|
|
|
|
func (s *cloudStack) OrgName() string { return s.orgName }
|
|
|
|
func (s *cloudStack) CloudName() string { return s.cloudName }
|
|
|
|
func (s *cloudStack) RunLocally() bool { return s.cloudName == managedCloudName }
|
Make some updates based on CR feedback
This change implements some feedback from @ellismg.
* Make backend.Stack an interface and let backends implement it,
enabling dynamic type testing/casting to access information
specific to that backend. For instance, the cloud.Stack conveys
the cloud URL, org name, and PPC name, for each stack.
* Similarly expose specialized backend.Backend interfaces,
local.Backend and cloud.Backend, to convey specific information.
* Redo a bunch of the commands in terms of these.
* Keeping with this theme, turn the CreateStack options into an
opaque interface{}, and let the specific backends expose their
own structures with their own settings (like PPC name in cloud).
* Show both the org and PPC names in the cloud column printed in
the stack ls command, in addition to the Pulumi Cloud URL.
Unrelated, but useful:
* Special case the 401 HTTP response and make a friendly error,
to tell the developer they must use `pulumi login`. This is
better than tossing raw "401: Unauthorized" errors in their face.
* Change the "Updating stack '..' in the Pulumi Cloud" message to
use the correct action verb ("Previewing", "Destroying", etc).
2017-12-03 16:51:18 +01:00
|
|
|
|
|
|
|
func (s *cloudStack) Remove(force bool) (bool, error) {
|
|
|
|
return backend.RemoveStack(s, force)
|
|
|
|
}
|
|
|
|
|
2018-05-05 20:57:09 +02:00
|
|
|
func (s *cloudStack) Preview(proj *workspace.Project, root string, m backend.UpdateMetadata,
|
|
|
|
opts backend.UpdateOptions, scopes backend.CancellationScopeSource) error {
|
|
|
|
return backend.PreviewStack(s, proj, root, m, opts, scopes)
|
|
|
|
}
|
|
|
|
|
Revise the way previews are controlled
I found the flag --force to be a strange name for skipping a preview,
since that name is usually reserved for operations that might be harmful
and yet you're coercing a tool to do it anyway, knowing there's a chance
you're going to shoot yourself in the foot.
I also found that what I almost always want in the situation where
--force was being used is to actually just run a preview and have the
confirmation auto-accepted. Going straight to --force isn't the right
thing in a CI scenario, where you actually want to run a preview first,
just to ensure there aren't any issues, before doing the update.
In a sense, there are four options here:
1. Run a preview, ask for confirmation, then do an update (the default).
2. Run a preview, auto-accept, and then do an update (the CI scenario).
3. Just run a preview with neither a confirmation nor an update (dry run).
4. Just do an update, without performing a preview beforehand (rare).
This change enables all four workflows in our CLI.
Rather than have an explosion of flags, we have a single flag,
--preview, which can specify the mode that we're operating in. The
following are the values which correlate to the above four modes:
1. "": default (no --preview specified)
2. "auto": auto-accept preview confirmation
3. "only": only run a preview, don't confirm or update
4. "skip": skip the preview altogether
As part of this change, I redid a bit of how the preview modes
were specified. Rather than booleans, which had some illegal
combinations, this change introduces a new enum type. Furthermore,
because the engine is wholly ignorant of these flags -- and only the
backend understands them -- it was confusing to me that
engine.UpdateOptions stored this flag, especially given that all
interesting engine options _also_ accepted a dryRun boolean. As of
this change, the backend.PreviewBehavior controls the preview options.
2018-04-28 23:50:17 +02:00
|
|
|
func (s *cloudStack) Update(proj *workspace.Project, root string, m backend.UpdateMetadata,
|
2018-05-05 20:57:09 +02:00
|
|
|
opts backend.UpdateOptions, scopes backend.CancellationScopeSource) error {
|
|
|
|
return backend.UpdateStack(s, proj, root, m, opts, scopes)
|
Make some updates based on CR feedback
This change implements some feedback from @ellismg.
* Make backend.Stack an interface and let backends implement it,
enabling dynamic type testing/casting to access information
specific to that backend. For instance, the cloud.Stack conveys
the cloud URL, org name, and PPC name, for each stack.
* Similarly expose specialized backend.Backend interfaces,
local.Backend and cloud.Backend, to convey specific information.
* Redo a bunch of the commands in terms of these.
* Keeping with this theme, turn the CreateStack options into an
opaque interface{}, and let the specific backends expose their
own structures with their own settings (like PPC name in cloud).
* Show both the org and PPC names in the cloud column printed in
the stack ls command, in addition to the Pulumi Cloud URL.
Unrelated, but useful:
* Special case the 401 HTTP response and make a friendly error,
to tell the developer they must use `pulumi login`. This is
better than tossing raw "401: Unauthorized" errors in their face.
* Change the "Updating stack '..' in the Pulumi Cloud" message to
use the correct action verb ("Previewing", "Destroying", etc).
2017-12-03 16:51:18 +01:00
|
|
|
}
|
|
|
|
|
Revise the way previews are controlled
I found the flag --force to be a strange name for skipping a preview,
since that name is usually reserved for operations that might be harmful
and yet you're coercing a tool to do it anyway, knowing there's a chance
you're going to shoot yourself in the foot.
I also found that what I almost always want in the situation where
--force was being used is to actually just run a preview and have the
confirmation auto-accepted. Going straight to --force isn't the right
thing in a CI scenario, where you actually want to run a preview first,
just to ensure there aren't any issues, before doing the update.
In a sense, there are four options here:
1. Run a preview, ask for confirmation, then do an update (the default).
2. Run a preview, auto-accept, and then do an update (the CI scenario).
3. Just run a preview with neither a confirmation nor an update (dry run).
4. Just do an update, without performing a preview beforehand (rare).
This change enables all four workflows in our CLI.
Rather than have an explosion of flags, we have a single flag,
--preview, which can specify the mode that we're operating in. The
following are the values which correlate to the above four modes:
1. "": default (no --preview specified)
2. "auto": auto-accept preview confirmation
3. "only": only run a preview, don't confirm or update
4. "skip": skip the preview altogether
As part of this change, I redid a bit of how the preview modes
were specified. Rather than booleans, which had some illegal
combinations, this change introduces a new enum type. Furthermore,
because the engine is wholly ignorant of these flags -- and only the
backend understands them -- it was confusing to me that
engine.UpdateOptions stored this flag, especially given that all
interesting engine options _also_ accepted a dryRun boolean. As of
this change, the backend.PreviewBehavior controls the preview options.
2018-04-28 23:50:17 +02:00
|
|
|
func (s *cloudStack) Refresh(proj *workspace.Project, root string, m backend.UpdateMetadata,
|
2018-05-05 20:57:09 +02:00
|
|
|
opts backend.UpdateOptions, scopes backend.CancellationScopeSource) error {
|
|
|
|
return backend.RefreshStack(s, proj, root, m, opts, scopes)
|
Implement a refresh command
This change implements a `pulumi refresh` command. It operates a bit
like `pulumi update`, and friends, in that it supports `--preview` and
`--diff`, along with the usual flags, and will update your checkpoint.
It works through substitution of the deploy.Source abstraction, which
generates a sequence of resource registration events. This new
deploy.RefreshSource takes in a prior checkpoint and will walk it,
refreshing the state via the associated resource providers by invoking
Read for each resource encountered, and merging the resulting state with
the prior checkpoint, to yield a new resource.Goal state. This state is
then fed through the engine in the usual ways with a few minor caveats:
namely, although the engine must generate steps for the logical
operations (permitting us to get nice summaries, progress, and diffs),
it mustn't actually carry them out because the state being imported
already reflects reality (a deleted resource has *already* been deleted,
so of course the engine need not perform the deletion). The diffing
logic also needs to know how to treat the case of refresh slightly
differently, because we are going to be diffing outputs and not inputs.
Note that support for managed stacks is not yet complete, since that
requires updates to the service to support a refresh endpoint. That
will be coming soon ...
2018-04-10 20:22:39 +02:00
|
|
|
}
|
|
|
|
|
Revise the way previews are controlled
I found the flag --force to be a strange name for skipping a preview,
since that name is usually reserved for operations that might be harmful
and yet you're coercing a tool to do it anyway, knowing there's a chance
you're going to shoot yourself in the foot.
I also found that what I almost always want in the situation where
--force was being used is to actually just run a preview and have the
confirmation auto-accepted. Going straight to --force isn't the right
thing in a CI scenario, where you actually want to run a preview first,
just to ensure there aren't any issues, before doing the update.
In a sense, there are four options here:
1. Run a preview, ask for confirmation, then do an update (the default).
2. Run a preview, auto-accept, and then do an update (the CI scenario).
3. Just run a preview with neither a confirmation nor an update (dry run).
4. Just do an update, without performing a preview beforehand (rare).
This change enables all four workflows in our CLI.
Rather than have an explosion of flags, we have a single flag,
--preview, which can specify the mode that we're operating in. The
following are the values which correlate to the above four modes:
1. "": default (no --preview specified)
2. "auto": auto-accept preview confirmation
3. "only": only run a preview, don't confirm or update
4. "skip": skip the preview altogether
As part of this change, I redid a bit of how the preview modes
were specified. Rather than booleans, which had some illegal
combinations, this change introduces a new enum type. Furthermore,
because the engine is wholly ignorant of these flags -- and only the
backend understands them -- it was confusing to me that
engine.UpdateOptions stored this flag, especially given that all
interesting engine options _also_ accepted a dryRun boolean. As of
this change, the backend.PreviewBehavior controls the preview options.
2018-04-28 23:50:17 +02:00
|
|
|
func (s *cloudStack) Destroy(proj *workspace.Project, root string, m backend.UpdateMetadata,
|
2018-05-05 20:57:09 +02:00
|
|
|
opts backend.UpdateOptions, scopes backend.CancellationScopeSource) error {
|
|
|
|
return backend.DestroyStack(s, proj, root, m, opts, scopes)
|
Make some updates based on CR feedback
This change implements some feedback from @ellismg.
* Make backend.Stack an interface and let backends implement it,
enabling dynamic type testing/casting to access information
specific to that backend. For instance, the cloud.Stack conveys
the cloud URL, org name, and PPC name, for each stack.
* Similarly expose specialized backend.Backend interfaces,
local.Backend and cloud.Backend, to convey specific information.
* Redo a bunch of the commands in terms of these.
* Keeping with this theme, turn the CreateStack options into an
opaque interface{}, and let the specific backends expose their
own structures with their own settings (like PPC name in cloud).
* Show both the org and PPC names in the cloud column printed in
the stack ls command, in addition to the Pulumi Cloud URL.
Unrelated, but useful:
* Special case the 401 HTTP response and make a friendly error,
to tell the developer they must use `pulumi login`. This is
better than tossing raw "401: Unauthorized" errors in their face.
* Change the "Updating stack '..' in the Pulumi Cloud" message to
use the correct action verb ("Previewing", "Destroying", etc).
2017-12-03 16:51:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *cloudStack) GetLogs(query operations.LogQuery) ([]operations.LogEntry, error) {
|
|
|
|
return backend.GetStackLogs(s, query)
|
|
|
|
}
|
2018-01-05 21:46:13 +01:00
|
|
|
|
2018-03-03 21:12:54 +01:00
|
|
|
func (s *cloudStack) ExportDeployment() (*apitype.UntypedDeployment, error) {
|
2018-01-05 21:46:13 +01:00
|
|
|
return backend.ExportStackDeployment(s)
|
|
|
|
}
|
|
|
|
|
2018-03-03 21:12:54 +01:00
|
|
|
func (s *cloudStack) ImportDeployment(deployment *apitype.UntypedDeployment) error {
|
2018-01-05 21:46:13 +01:00
|
|
|
return backend.ImportStackDeployment(s, deployment)
|
|
|
|
}
|
2018-04-20 08:54:33 +02:00
|
|
|
|
|
|
|
func (s *cloudStack) ConsoleURL() (string, error) {
|
|
|
|
path, err := s.b.StackConsoleURL(s.Name())
|
|
|
|
if err != nil {
|
|
|
|
return "", nil
|
|
|
|
}
|
|
|
|
url := s.b.CloudConsoleURL(path)
|
|
|
|
if url == "" {
|
|
|
|
return "", errors.New("could not determine clould console URL")
|
|
|
|
}
|
|
|
|
return url, nil
|
|
|
|
}
|