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
|
|
|
// Copyright 2016-2017, Pulumi Corporation. All rights reserved.
|
|
|
|
|
|
|
|
package cloud
|
|
|
|
|
|
|
|
import (
|
2018-01-05 21:46:13 +01:00
|
|
|
"encoding/json"
|
|
|
|
|
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/backend/cloud/apitype"
|
|
|
|
"github.com/pulumi/pulumi/pkg/engine"
|
|
|
|
"github.com/pulumi/pulumi/pkg/operations"
|
2018-01-08 22:01:40 +01:00
|
|
|
"github.com/pulumi/pulumi/pkg/pack"
|
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/resource"
|
|
|
|
"github.com/pulumi/pulumi/pkg/resource/config"
|
|
|
|
"github.com/pulumi/pulumi/pkg/resource/deploy"
|
|
|
|
"github.com/pulumi/pulumi/pkg/tokens"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Stack is a cloud stack. This simply adds some cloud-specific properties atop the standard backend stack interface.
|
|
|
|
type Stack interface {
|
|
|
|
backend.Stack
|
|
|
|
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.
|
|
|
|
}
|
|
|
|
|
|
|
|
// cloudStack is a cloud stack descriptor.
|
|
|
|
type cloudStack struct {
|
|
|
|
name tokens.QName // 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.
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
var resources []*resource.State
|
|
|
|
for _, res := range apistack.Resources {
|
|
|
|
resources = append(resources, resource.NewState(
|
|
|
|
tokens.Type(res.Type),
|
|
|
|
resource.URN(res.URN),
|
|
|
|
res.Custom,
|
|
|
|
false,
|
|
|
|
resource.ID(res.ID),
|
|
|
|
resource.NewPropertyMapFromMap(res.Inputs),
|
|
|
|
resource.NewPropertyMapFromMap(res.Outputs),
|
|
|
|
resource.URN(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,
|
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{
|
|
|
|
name: stackName,
|
|
|
|
cloudURL: b.cloudURL,
|
|
|
|
orgName: apistack.OrgName,
|
|
|
|
cloudName: apistack.CloudName,
|
|
|
|
config: nil, // TODO[pulumi/pulumi-service#249]: add the config variables.
|
|
|
|
snapshot: snapshot,
|
|
|
|
b: b,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *cloudStack) Name() tokens.QName { 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) Remove(force bool) (bool, error) {
|
|
|
|
return backend.RemoveStack(s, force)
|
|
|
|
}
|
|
|
|
|
2018-01-08 22:01:40 +01:00
|
|
|
func (s *cloudStack) Preview(pkg *pack.Package, root string, debug bool, opts engine.PreviewOptions) error {
|
|
|
|
return backend.PreviewStack(s, pkg, root, debug, opts)
|
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
|
|
|
}
|
|
|
|
|
2018-01-08 22:01:40 +01:00
|
|
|
func (s *cloudStack) Update(pkg *pack.Package, root string, debug bool, opts engine.DeployOptions) error {
|
|
|
|
return backend.UpdateStack(s, pkg, root, debug, opts)
|
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
|
|
|
}
|
|
|
|
|
2018-01-08 22:01:40 +01:00
|
|
|
func (s *cloudStack) Destroy(pkg *pack.Package, root string, debug bool, opts engine.DestroyOptions) error {
|
|
|
|
return backend.DestroyStack(s, pkg, root, debug, opts)
|
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
|
|
|
|
|
|
|
func (s *cloudStack) ExportDeployment() (json.RawMessage, error) {
|
|
|
|
return backend.ExportStackDeployment(s)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *cloudStack) ImportDeployment(deployment json.RawMessage) error {
|
|
|
|
return backend.ImportStackDeployment(s, deployment)
|
|
|
|
}
|