2018-05-22 21:43:36 +02:00
|
|
|
// Copyright 2016-2018, Pulumi Corporation.
|
|
|
|
//
|
|
|
|
// 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.
|
Improve the overall cloud CLI experience
This improves the overall cloud CLI experience workflow.
Now whether a stack is local or cloud is inherent to the stack
itself. If you interact with a cloud stack, we transparently talk
to the cloud; if you interact with a local stack, we just do the
right thing, and perform all operations locally. Aside from sometimes
seeing a cloud emoji pop-up ☁️, the experience is quite similar.
For example, to initialize a new cloud stack, simply:
$ pulumi login
Logging into Pulumi Cloud: https://pulumi.com/
Enter Pulumi access token: <enter your token>
$ pulumi stack init my-cloud-stack
Note that you may log into a specific cloud if you'd like. For
now, this is just for our own testing purposes, but someday when we
support custom clouds (e.g., Enterprise), you can just say:
$ pulumi login --cloud-url https://corp.acme.my-ppc.net:9873
The cloud is now the default. If you instead prefer a "fire and
forget" style of stack, you can skip the login and pass `--local`:
$ pulumi stack init my-faf-stack --local
If you are logged in and run `pulumi`, we tell you as much:
$ pulumi
Usage:
pulumi [command]
// as before...
Currently logged into the Pulumi Cloud ☁️
https://pulumi.com/
And if you list your stacks, we tell you which one is local or not:
$ pulumi stack ls
NAME LAST UPDATE RESOURCE COUNT CLOUD URL
my-cloud-stack 2017-12-01 ... 3 https://pulumi.com/
my-faf-stack n/a 0 n/a
And `pulumi stack` by itself prints information like your cloud org,
PPC name, and so on, in addition to the usuals.
I shall write up more details and make sure to document these changes.
This change also fairly significantly refactors the layout of cloud
versus local logic, so that the cmd/ package is resonsible for CLI
things, and the new pkg/backend/ package is responsible for the
backends. The following is the overall resulting package architecture:
* The backend.Backend interface can be implemented to substitute
a new backend. This has operations to get and list stacks,
perform updates, and so on.
* The backend.Stack struct is a wrapper around a stack that has
or is being manipulated by a Backend. It resembles our existing
Stack notions in the engine, but carries additional metadata
about its source. Notably, it offers functions that allow
operations like updating and deleting on the Backend from which
it came.
* There is very little else in the pkg/backend/ package.
* A new package, pkg/backend/local/, encapsulates all local state
management for "fire and forget" scenarios. It simply implements
the above logic and contains anything specific to the local
experience.
* A peer package, pkg/backend/cloud/, encapsulates all logic
required for the cloud experience. This includes its subpackage
apitype/ which contains JSON schema descriptions required for
REST calls against the cloud backend. It also contains handy
functions to list which clouds we have authenticated with.
* A subpackage here, pkg/backend/state/, is not a provider at all.
Instead, it contains all of the state management functions that
are currently shared between local and cloud backends. This
includes configuration logic -- including encryption -- as well
as logic pertaining to which stacks are known to the workspace.
This addresses pulumi/pulumi#629 and pulumi/pulumi#494.
2017-12-02 16:29:46 +01:00
|
|
|
|
|
|
|
package backend
|
|
|
|
|
|
|
|
import (
|
2018-05-08 03:23:03 +02:00
|
|
|
"context"
|
2018-10-23 23:53:52 +02:00
|
|
|
"fmt"
|
2018-05-22 01:17:12 +02:00
|
|
|
"path/filepath"
|
2018-04-11 19:08:32 +02:00
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
2019-05-07 01:01:47 +02:00
|
|
|
|
2020-04-14 10:30:25 +02:00
|
|
|
"github.com/pulumi/pulumi/pkg/v2/engine"
|
|
|
|
"github.com/pulumi/pulumi/pkg/v2/operations"
|
|
|
|
"github.com/pulumi/pulumi/pkg/v2/resource/deploy"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v2/go/common/apitype"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v2/go/common/resource/config"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v2/go/common/tokens"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v2/go/common/util/contract"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v2/go/common/util/gitutil"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v2/go/common/util/result"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v2/go/common/workspace"
|
Improve the overall cloud CLI experience
This improves the overall cloud CLI experience workflow.
Now whether a stack is local or cloud is inherent to the stack
itself. If you interact with a cloud stack, we transparently talk
to the cloud; if you interact with a local stack, we just do the
right thing, and perform all operations locally. Aside from sometimes
seeing a cloud emoji pop-up ☁️, the experience is quite similar.
For example, to initialize a new cloud stack, simply:
$ pulumi login
Logging into Pulumi Cloud: https://pulumi.com/
Enter Pulumi access token: <enter your token>
$ pulumi stack init my-cloud-stack
Note that you may log into a specific cloud if you'd like. For
now, this is just for our own testing purposes, but someday when we
support custom clouds (e.g., Enterprise), you can just say:
$ pulumi login --cloud-url https://corp.acme.my-ppc.net:9873
The cloud is now the default. If you instead prefer a "fire and
forget" style of stack, you can skip the login and pass `--local`:
$ pulumi stack init my-faf-stack --local
If you are logged in and run `pulumi`, we tell you as much:
$ pulumi
Usage:
pulumi [command]
// as before...
Currently logged into the Pulumi Cloud ☁️
https://pulumi.com/
And if you list your stacks, we tell you which one is local or not:
$ pulumi stack ls
NAME LAST UPDATE RESOURCE COUNT CLOUD URL
my-cloud-stack 2017-12-01 ... 3 https://pulumi.com/
my-faf-stack n/a 0 n/a
And `pulumi stack` by itself prints information like your cloud org,
PPC name, and so on, in addition to the usuals.
I shall write up more details and make sure to document these changes.
This change also fairly significantly refactors the layout of cloud
versus local logic, so that the cmd/ package is resonsible for CLI
things, and the new pkg/backend/ package is responsible for the
backends. The following is the overall resulting package architecture:
* The backend.Backend interface can be implemented to substitute
a new backend. This has operations to get and list stacks,
perform updates, and so on.
* The backend.Stack struct is a wrapper around a stack that has
or is being manipulated by a Backend. It resembles our existing
Stack notions in the engine, but carries additional metadata
about its source. Notably, it offers functions that allow
operations like updating and deleting on the Backend from which
it came.
* There is very little else in the pkg/backend/ package.
* A new package, pkg/backend/local/, encapsulates all local state
management for "fire and forget" scenarios. It simply implements
the above logic and contains anything specific to the local
experience.
* A peer package, pkg/backend/cloud/, encapsulates all logic
required for the cloud experience. This includes its subpackage
apitype/ which contains JSON schema descriptions required for
REST calls against the cloud backend. It also contains handy
functions to list which clouds we have authenticated with.
* A subpackage here, pkg/backend/state/, is not a provider at all.
Instead, it contains all of the state management functions that
are currently shared between local and cloud backends. This
includes configuration logic -- including encryption -- as well
as logic pertaining to which stacks are known to the workspace.
This addresses pulumi/pulumi#629 and pulumi/pulumi#494.
2017-12-02 16:29:46 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// Stack is a stack associated with a particular backend implementation.
|
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
|
|
|
type Stack interface {
|
2018-09-05 16:20:25 +02:00
|
|
|
Ref() StackReference // this stack's identity.
|
2018-05-23 00:39:13 +02:00
|
|
|
Snapshot(ctx context.Context) (*deploy.Snapshot, error) // the latest deployment snapshot.
|
|
|
|
Backend() Backend // the backend this stack belongs to.
|
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-05-05 20:57:09 +02:00
|
|
|
// Preview changes to this stack.
|
2019-03-20 00:21:50 +01:00
|
|
|
Preview(ctx context.Context, op UpdateOperation) (engine.ResourceChanges, result.Result)
|
2018-01-25 03:22:41 +01:00
|
|
|
// Update this stack.
|
2019-03-20 00:21:50 +01:00
|
|
|
Update(ctx context.Context, op UpdateOperation) (engine.ResourceChanges, result.Result)
|
2020-10-14 13:51:53 +02:00
|
|
|
// Import resources into this stack.
|
|
|
|
Import(ctx context.Context, op UpdateOperation, imports []deploy.Import) (engine.ResourceChanges, result.Result)
|
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
|
|
|
// Refresh this stack's state from the cloud provider.
|
2019-03-20 00:21:50 +01:00
|
|
|
Refresh(ctx context.Context, op UpdateOperation) (engine.ResourceChanges, result.Result)
|
2018-01-25 03:22:41 +01:00
|
|
|
// Destroy this stack's resources.
|
2019-03-20 00:21:50 +01:00
|
|
|
Destroy(ctx context.Context, op UpdateOperation) (engine.ResourceChanges, result.Result)
|
2019-11-06 21:56:29 +01:00
|
|
|
// Watch this stack.
|
|
|
|
Watch(ctx context.Context, op UpdateOperation) result.Result
|
2018-05-08 03:23:03 +02:00
|
|
|
|
|
|
|
// remove this stack.
|
|
|
|
Remove(ctx context.Context, force bool) (bool, error)
|
2019-03-14 23:32:10 +01:00
|
|
|
// rename this stack.
|
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 01:55:48 +01:00
|
|
|
Rename(ctx context.Context, newName tokens.QName) (StackReference, error)
|
2018-05-08 03:23:03 +02:00
|
|
|
// list log entries for this stack.
|
2019-04-19 00:57:54 +02:00
|
|
|
GetLogs(ctx context.Context, cfg StackConfiguration, query operations.LogQuery) ([]operations.LogEntry, error)
|
2018-05-08 03:23:03 +02:00
|
|
|
// export this stack's deployment.
|
|
|
|
ExportDeployment(ctx context.Context) (*apitype.UntypedDeployment, error)
|
|
|
|
// import the given deployment into this stack.
|
|
|
|
ImportDeployment(ctx context.Context, deployment *apitype.UntypedDeployment) error
|
Improve the overall cloud CLI experience
This improves the overall cloud CLI experience workflow.
Now whether a stack is local or cloud is inherent to the stack
itself. If you interact with a cloud stack, we transparently talk
to the cloud; if you interact with a local stack, we just do the
right thing, and perform all operations locally. Aside from sometimes
seeing a cloud emoji pop-up ☁️, the experience is quite similar.
For example, to initialize a new cloud stack, simply:
$ pulumi login
Logging into Pulumi Cloud: https://pulumi.com/
Enter Pulumi access token: <enter your token>
$ pulumi stack init my-cloud-stack
Note that you may log into a specific cloud if you'd like. For
now, this is just for our own testing purposes, but someday when we
support custom clouds (e.g., Enterprise), you can just say:
$ pulumi login --cloud-url https://corp.acme.my-ppc.net:9873
The cloud is now the default. If you instead prefer a "fire and
forget" style of stack, you can skip the login and pass `--local`:
$ pulumi stack init my-faf-stack --local
If you are logged in and run `pulumi`, we tell you as much:
$ pulumi
Usage:
pulumi [command]
// as before...
Currently logged into the Pulumi Cloud ☁️
https://pulumi.com/
And if you list your stacks, we tell you which one is local or not:
$ pulumi stack ls
NAME LAST UPDATE RESOURCE COUNT CLOUD URL
my-cloud-stack 2017-12-01 ... 3 https://pulumi.com/
my-faf-stack n/a 0 n/a
And `pulumi stack` by itself prints information like your cloud org,
PPC name, and so on, in addition to the usuals.
I shall write up more details and make sure to document these changes.
This change also fairly significantly refactors the layout of cloud
versus local logic, so that the cmd/ package is resonsible for CLI
things, and the new pkg/backend/ package is responsible for the
backends. The following is the overall resulting package architecture:
* The backend.Backend interface can be implemented to substitute
a new backend. This has operations to get and list stacks,
perform updates, and so on.
* The backend.Stack struct is a wrapper around a stack that has
or is being manipulated by a Backend. It resembles our existing
Stack notions in the engine, but carries additional metadata
about its source. Notably, it offers functions that allow
operations like updating and deleting on the Backend from which
it came.
* There is very little else in the pkg/backend/ package.
* A new package, pkg/backend/local/, encapsulates all local state
management for "fire and forget" scenarios. It simply implements
the above logic and contains anything specific to the local
experience.
* A peer package, pkg/backend/cloud/, encapsulates all logic
required for the cloud experience. This includes its subpackage
apitype/ which contains JSON schema descriptions required for
REST calls against the cloud backend. It also contains handy
functions to list which clouds we have authenticated with.
* A subpackage here, pkg/backend/state/, is not a provider at all.
Instead, it contains all of the state management functions that
are currently shared between local and cloud backends. This
includes configuration logic -- including encryption -- as well
as logic pertaining to which stacks are known to the workspace.
This addresses pulumi/pulumi#629 and pulumi/pulumi#494.
2017-12-02 16:29:46 +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
|
|
|
// RemoveStack returns the stack, or returns an error if it cannot.
|
2018-05-08 03:23:03 +02:00
|
|
|
func RemoveStack(ctx context.Context, s Stack, force bool) (bool, error) {
|
2019-10-14 23:30:42 +02:00
|
|
|
return s.Backend().RemoveStack(ctx, s, force)
|
Improve the overall cloud CLI experience
This improves the overall cloud CLI experience workflow.
Now whether a stack is local or cloud is inherent to the stack
itself. If you interact with a cloud stack, we transparently talk
to the cloud; if you interact with a local stack, we just do the
right thing, and perform all operations locally. Aside from sometimes
seeing a cloud emoji pop-up ☁️, the experience is quite similar.
For example, to initialize a new cloud stack, simply:
$ pulumi login
Logging into Pulumi Cloud: https://pulumi.com/
Enter Pulumi access token: <enter your token>
$ pulumi stack init my-cloud-stack
Note that you may log into a specific cloud if you'd like. For
now, this is just for our own testing purposes, but someday when we
support custom clouds (e.g., Enterprise), you can just say:
$ pulumi login --cloud-url https://corp.acme.my-ppc.net:9873
The cloud is now the default. If you instead prefer a "fire and
forget" style of stack, you can skip the login and pass `--local`:
$ pulumi stack init my-faf-stack --local
If you are logged in and run `pulumi`, we tell you as much:
$ pulumi
Usage:
pulumi [command]
// as before...
Currently logged into the Pulumi Cloud ☁️
https://pulumi.com/
And if you list your stacks, we tell you which one is local or not:
$ pulumi stack ls
NAME LAST UPDATE RESOURCE COUNT CLOUD URL
my-cloud-stack 2017-12-01 ... 3 https://pulumi.com/
my-faf-stack n/a 0 n/a
And `pulumi stack` by itself prints information like your cloud org,
PPC name, and so on, in addition to the usuals.
I shall write up more details and make sure to document these changes.
This change also fairly significantly refactors the layout of cloud
versus local logic, so that the cmd/ package is resonsible for CLI
things, and the new pkg/backend/ package is responsible for the
backends. The following is the overall resulting package architecture:
* The backend.Backend interface can be implemented to substitute
a new backend. This has operations to get and list stacks,
perform updates, and so on.
* The backend.Stack struct is a wrapper around a stack that has
or is being manipulated by a Backend. It resembles our existing
Stack notions in the engine, but carries additional metadata
about its source. Notably, it offers functions that allow
operations like updating and deleting on the Backend from which
it came.
* There is very little else in the pkg/backend/ package.
* A new package, pkg/backend/local/, encapsulates all local state
management for "fire and forget" scenarios. It simply implements
the above logic and contains anything specific to the local
experience.
* A peer package, pkg/backend/cloud/, encapsulates all logic
required for the cloud experience. This includes its subpackage
apitype/ which contains JSON schema descriptions required for
REST calls against the cloud backend. It also contains handy
functions to list which clouds we have authenticated with.
* A subpackage here, pkg/backend/state/, is not a provider at all.
Instead, it contains all of the state management functions that
are currently shared between local and cloud backends. This
includes configuration logic -- including encryption -- as well
as logic pertaining to which stacks are known to the workspace.
This addresses pulumi/pulumi#629 and pulumi/pulumi#494.
2017-12-02 16:29:46 +01:00
|
|
|
}
|
|
|
|
|
2019-08-12 09:22:42 +02:00
|
|
|
// RenameStack renames the stack, or returns an error if it cannot.
|
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 01:55:48 +01:00
|
|
|
func RenameStack(ctx context.Context, s Stack, newName tokens.QName) (StackReference, error) {
|
2019-10-14 23:30:42 +02:00
|
|
|
return s.Backend().RenameStack(ctx, s, newName)
|
2019-03-14 23:32:10 +01:00
|
|
|
}
|
|
|
|
|
2018-05-05 20:57:09 +02:00
|
|
|
// PreviewStack previews changes to this stack.
|
2019-03-20 00:21:50 +01:00
|
|
|
func PreviewStack(ctx context.Context, s Stack, op UpdateOperation) (engine.ResourceChanges, result.Result) {
|
2019-10-14 23:30:42 +02:00
|
|
|
return s.Backend().Preview(ctx, s, op)
|
2018-05-05 20:57:09 +02: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
|
|
|
// UpdateStack updates the target stack with the current workspace's contents (config and code).
|
2019-03-20 00:21:50 +01:00
|
|
|
func UpdateStack(ctx context.Context, s Stack, op UpdateOperation) (engine.ResourceChanges, result.Result) {
|
2019-10-14 23:30:42 +02:00
|
|
|
return s.Backend().Update(ctx, s, op)
|
Improve the overall cloud CLI experience
This improves the overall cloud CLI experience workflow.
Now whether a stack is local or cloud is inherent to the stack
itself. If you interact with a cloud stack, we transparently talk
to the cloud; if you interact with a local stack, we just do the
right thing, and perform all operations locally. Aside from sometimes
seeing a cloud emoji pop-up ☁️, the experience is quite similar.
For example, to initialize a new cloud stack, simply:
$ pulumi login
Logging into Pulumi Cloud: https://pulumi.com/
Enter Pulumi access token: <enter your token>
$ pulumi stack init my-cloud-stack
Note that you may log into a specific cloud if you'd like. For
now, this is just for our own testing purposes, but someday when we
support custom clouds (e.g., Enterprise), you can just say:
$ pulumi login --cloud-url https://corp.acme.my-ppc.net:9873
The cloud is now the default. If you instead prefer a "fire and
forget" style of stack, you can skip the login and pass `--local`:
$ pulumi stack init my-faf-stack --local
If you are logged in and run `pulumi`, we tell you as much:
$ pulumi
Usage:
pulumi [command]
// as before...
Currently logged into the Pulumi Cloud ☁️
https://pulumi.com/
And if you list your stacks, we tell you which one is local or not:
$ pulumi stack ls
NAME LAST UPDATE RESOURCE COUNT CLOUD URL
my-cloud-stack 2017-12-01 ... 3 https://pulumi.com/
my-faf-stack n/a 0 n/a
And `pulumi stack` by itself prints information like your cloud org,
PPC name, and so on, in addition to the usuals.
I shall write up more details and make sure to document these changes.
This change also fairly significantly refactors the layout of cloud
versus local logic, so that the cmd/ package is resonsible for CLI
things, and the new pkg/backend/ package is responsible for the
backends. The following is the overall resulting package architecture:
* The backend.Backend interface can be implemented to substitute
a new backend. This has operations to get and list stacks,
perform updates, and so on.
* The backend.Stack struct is a wrapper around a stack that has
or is being manipulated by a Backend. It resembles our existing
Stack notions in the engine, but carries additional metadata
about its source. Notably, it offers functions that allow
operations like updating and deleting on the Backend from which
it came.
* There is very little else in the pkg/backend/ package.
* A new package, pkg/backend/local/, encapsulates all local state
management for "fire and forget" scenarios. It simply implements
the above logic and contains anything specific to the local
experience.
* A peer package, pkg/backend/cloud/, encapsulates all logic
required for the cloud experience. This includes its subpackage
apitype/ which contains JSON schema descriptions required for
REST calls against the cloud backend. It also contains handy
functions to list which clouds we have authenticated with.
* A subpackage here, pkg/backend/state/, is not a provider at all.
Instead, it contains all of the state management functions that
are currently shared between local and cloud backends. This
includes configuration logic -- including encryption -- as well
as logic pertaining to which stacks are known to the workspace.
This addresses pulumi/pulumi#629 and pulumi/pulumi#494.
2017-12-02 16:29:46 +01:00
|
|
|
}
|
|
|
|
|
2020-10-14 13:51:53 +02:00
|
|
|
// ImportStack updates the target stack with the current workspace's contents (config and code).
|
|
|
|
func ImportStack(ctx context.Context, s Stack, op UpdateOperation,
|
|
|
|
imports []deploy.Import) (engine.ResourceChanges, result.Result) {
|
|
|
|
|
|
|
|
return s.Backend().Import(ctx, s, op, imports)
|
|
|
|
}
|
|
|
|
|
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
|
|
|
// RefreshStack refresh's the stack's state from the cloud provider.
|
2019-03-20 00:21:50 +01:00
|
|
|
func RefreshStack(ctx context.Context, s Stack, op UpdateOperation) (engine.ResourceChanges, result.Result) {
|
2019-10-14 23:30:42 +02:00
|
|
|
return s.Backend().Refresh(ctx, s, op)
|
Improve the overall cloud CLI experience
This improves the overall cloud CLI experience workflow.
Now whether a stack is local or cloud is inherent to the stack
itself. If you interact with a cloud stack, we transparently talk
to the cloud; if you interact with a local stack, we just do the
right thing, and perform all operations locally. Aside from sometimes
seeing a cloud emoji pop-up ☁️, the experience is quite similar.
For example, to initialize a new cloud stack, simply:
$ pulumi login
Logging into Pulumi Cloud: https://pulumi.com/
Enter Pulumi access token: <enter your token>
$ pulumi stack init my-cloud-stack
Note that you may log into a specific cloud if you'd like. For
now, this is just for our own testing purposes, but someday when we
support custom clouds (e.g., Enterprise), you can just say:
$ pulumi login --cloud-url https://corp.acme.my-ppc.net:9873
The cloud is now the default. If you instead prefer a "fire and
forget" style of stack, you can skip the login and pass `--local`:
$ pulumi stack init my-faf-stack --local
If you are logged in and run `pulumi`, we tell you as much:
$ pulumi
Usage:
pulumi [command]
// as before...
Currently logged into the Pulumi Cloud ☁️
https://pulumi.com/
And if you list your stacks, we tell you which one is local or not:
$ pulumi stack ls
NAME LAST UPDATE RESOURCE COUNT CLOUD URL
my-cloud-stack 2017-12-01 ... 3 https://pulumi.com/
my-faf-stack n/a 0 n/a
And `pulumi stack` by itself prints information like your cloud org,
PPC name, and so on, in addition to the usuals.
I shall write up more details and make sure to document these changes.
This change also fairly significantly refactors the layout of cloud
versus local logic, so that the cmd/ package is resonsible for CLI
things, and the new pkg/backend/ package is responsible for the
backends. The following is the overall resulting package architecture:
* The backend.Backend interface can be implemented to substitute
a new backend. This has operations to get and list stacks,
perform updates, and so on.
* The backend.Stack struct is a wrapper around a stack that has
or is being manipulated by a Backend. It resembles our existing
Stack notions in the engine, but carries additional metadata
about its source. Notably, it offers functions that allow
operations like updating and deleting on the Backend from which
it came.
* There is very little else in the pkg/backend/ package.
* A new package, pkg/backend/local/, encapsulates all local state
management for "fire and forget" scenarios. It simply implements
the above logic and contains anything specific to the local
experience.
* A peer package, pkg/backend/cloud/, encapsulates all logic
required for the cloud experience. This includes its subpackage
apitype/ which contains JSON schema descriptions required for
REST calls against the cloud backend. It also contains handy
functions to list which clouds we have authenticated with.
* A subpackage here, pkg/backend/state/, is not a provider at all.
Instead, it contains all of the state management functions that
are currently shared between local and cloud backends. This
includes configuration logic -- including encryption -- as well
as logic pertaining to which stacks are known to the workspace.
This addresses pulumi/pulumi#629 and pulumi/pulumi#494.
2017-12-02 16:29:46 +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
|
|
|
// DestroyStack destroys all of this stack's resources.
|
2019-03-20 00:21:50 +01:00
|
|
|
func DestroyStack(ctx context.Context, s Stack, op UpdateOperation) (engine.ResourceChanges, result.Result) {
|
2019-10-14 23:30:42 +02:00
|
|
|
return s.Backend().Destroy(ctx, s, op)
|
Improve the overall cloud CLI experience
This improves the overall cloud CLI experience workflow.
Now whether a stack is local or cloud is inherent to the stack
itself. If you interact with a cloud stack, we transparently talk
to the cloud; if you interact with a local stack, we just do the
right thing, and perform all operations locally. Aside from sometimes
seeing a cloud emoji pop-up ☁️, the experience is quite similar.
For example, to initialize a new cloud stack, simply:
$ pulumi login
Logging into Pulumi Cloud: https://pulumi.com/
Enter Pulumi access token: <enter your token>
$ pulumi stack init my-cloud-stack
Note that you may log into a specific cloud if you'd like. For
now, this is just for our own testing purposes, but someday when we
support custom clouds (e.g., Enterprise), you can just say:
$ pulumi login --cloud-url https://corp.acme.my-ppc.net:9873
The cloud is now the default. If you instead prefer a "fire and
forget" style of stack, you can skip the login and pass `--local`:
$ pulumi stack init my-faf-stack --local
If you are logged in and run `pulumi`, we tell you as much:
$ pulumi
Usage:
pulumi [command]
// as before...
Currently logged into the Pulumi Cloud ☁️
https://pulumi.com/
And if you list your stacks, we tell you which one is local or not:
$ pulumi stack ls
NAME LAST UPDATE RESOURCE COUNT CLOUD URL
my-cloud-stack 2017-12-01 ... 3 https://pulumi.com/
my-faf-stack n/a 0 n/a
And `pulumi stack` by itself prints information like your cloud org,
PPC name, and so on, in addition to the usuals.
I shall write up more details and make sure to document these changes.
This change also fairly significantly refactors the layout of cloud
versus local logic, so that the cmd/ package is resonsible for CLI
things, and the new pkg/backend/ package is responsible for the
backends. The following is the overall resulting package architecture:
* The backend.Backend interface can be implemented to substitute
a new backend. This has operations to get and list stacks,
perform updates, and so on.
* The backend.Stack struct is a wrapper around a stack that has
or is being manipulated by a Backend. It resembles our existing
Stack notions in the engine, but carries additional metadata
about its source. Notably, it offers functions that allow
operations like updating and deleting on the Backend from which
it came.
* There is very little else in the pkg/backend/ package.
* A new package, pkg/backend/local/, encapsulates all local state
management for "fire and forget" scenarios. It simply implements
the above logic and contains anything specific to the local
experience.
* A peer package, pkg/backend/cloud/, encapsulates all logic
required for the cloud experience. This includes its subpackage
apitype/ which contains JSON schema descriptions required for
REST calls against the cloud backend. It also contains handy
functions to list which clouds we have authenticated with.
* A subpackage here, pkg/backend/state/, is not a provider at all.
Instead, it contains all of the state management functions that
are currently shared between local and cloud backends. This
includes configuration logic -- including encryption -- as well
as logic pertaining to which stacks are known to the workspace.
This addresses pulumi/pulumi#629 and pulumi/pulumi#494.
2017-12-02 16:29:46 +01:00
|
|
|
}
|
|
|
|
|
2019-11-06 21:56:29 +01:00
|
|
|
// WatchStack watches the projects working directory for changes and automatically updates the
|
|
|
|
// active stack.
|
|
|
|
func WatchStack(ctx context.Context, s Stack, op UpdateOperation) result.Result {
|
|
|
|
return s.Backend().Watch(ctx, s, op)
|
|
|
|
}
|
|
|
|
|
2018-04-27 01:13:52 +02:00
|
|
|
// GetLatestConfiguration returns the configuration for the most recent deployment of the stack.
|
|
|
|
func GetLatestConfiguration(ctx context.Context, s Stack) (config.Map, error) {
|
2019-10-14 23:30:42 +02:00
|
|
|
return s.Backend().GetLatestConfiguration(ctx, s)
|
2018-04-27 01:13:52 +02: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
|
|
|
// GetStackLogs fetches a list of log entries for the current stack in the current backend.
|
2019-04-19 00:57:54 +02:00
|
|
|
func GetStackLogs(ctx context.Context, s Stack, cfg StackConfiguration,
|
|
|
|
query operations.LogQuery) ([]operations.LogEntry, error) {
|
2019-10-14 23:30:42 +02:00
|
|
|
return s.Backend().GetLogs(ctx, s, cfg, query)
|
Improve the overall cloud CLI experience
This improves the overall cloud CLI experience workflow.
Now whether a stack is local or cloud is inherent to the stack
itself. If you interact with a cloud stack, we transparently talk
to the cloud; if you interact with a local stack, we just do the
right thing, and perform all operations locally. Aside from sometimes
seeing a cloud emoji pop-up ☁️, the experience is quite similar.
For example, to initialize a new cloud stack, simply:
$ pulumi login
Logging into Pulumi Cloud: https://pulumi.com/
Enter Pulumi access token: <enter your token>
$ pulumi stack init my-cloud-stack
Note that you may log into a specific cloud if you'd like. For
now, this is just for our own testing purposes, but someday when we
support custom clouds (e.g., Enterprise), you can just say:
$ pulumi login --cloud-url https://corp.acme.my-ppc.net:9873
The cloud is now the default. If you instead prefer a "fire and
forget" style of stack, you can skip the login and pass `--local`:
$ pulumi stack init my-faf-stack --local
If you are logged in and run `pulumi`, we tell you as much:
$ pulumi
Usage:
pulumi [command]
// as before...
Currently logged into the Pulumi Cloud ☁️
https://pulumi.com/
And if you list your stacks, we tell you which one is local or not:
$ pulumi stack ls
NAME LAST UPDATE RESOURCE COUNT CLOUD URL
my-cloud-stack 2017-12-01 ... 3 https://pulumi.com/
my-faf-stack n/a 0 n/a
And `pulumi stack` by itself prints information like your cloud org,
PPC name, and so on, in addition to the usuals.
I shall write up more details and make sure to document these changes.
This change also fairly significantly refactors the layout of cloud
versus local logic, so that the cmd/ package is resonsible for CLI
things, and the new pkg/backend/ package is responsible for the
backends. The following is the overall resulting package architecture:
* The backend.Backend interface can be implemented to substitute
a new backend. This has operations to get and list stacks,
perform updates, and so on.
* The backend.Stack struct is a wrapper around a stack that has
or is being manipulated by a Backend. It resembles our existing
Stack notions in the engine, but carries additional metadata
about its source. Notably, it offers functions that allow
operations like updating and deleting on the Backend from which
it came.
* There is very little else in the pkg/backend/ package.
* A new package, pkg/backend/local/, encapsulates all local state
management for "fire and forget" scenarios. It simply implements
the above logic and contains anything specific to the local
experience.
* A peer package, pkg/backend/cloud/, encapsulates all logic
required for the cloud experience. This includes its subpackage
apitype/ which contains JSON schema descriptions required for
REST calls against the cloud backend. It also contains handy
functions to list which clouds we have authenticated with.
* A subpackage here, pkg/backend/state/, is not a provider at all.
Instead, it contains all of the state management functions that
are currently shared between local and cloud backends. This
includes configuration logic -- including encryption -- as well
as logic pertaining to which stacks are known to the workspace.
This addresses pulumi/pulumi#629 and pulumi/pulumi#494.
2017-12-02 16:29:46 +01:00
|
|
|
}
|
2018-01-05 21:46:13 +01:00
|
|
|
|
|
|
|
// ExportStackDeployment exports the given stack's deployment as an opaque JSON message.
|
2018-05-08 03:23:03 +02:00
|
|
|
func ExportStackDeployment(ctx context.Context, s Stack) (*apitype.UntypedDeployment, error) {
|
2019-10-14 23:30:42 +02:00
|
|
|
return s.Backend().ExportDeployment(ctx, s)
|
2018-01-05 21:46:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// ImportStackDeployment imports the given deployment into the indicated stack.
|
2018-05-08 03:23:03 +02:00
|
|
|
func ImportStackDeployment(ctx context.Context, s Stack, deployment *apitype.UntypedDeployment) error {
|
2019-10-14 23:30:42 +02:00
|
|
|
return s.Backend().ImportDeployment(ctx, s, deployment)
|
2018-01-05 21:46:13 +01:00
|
|
|
}
|
2018-04-11 19:08:32 +02:00
|
|
|
|
2019-01-04 22:23:47 +01:00
|
|
|
// GetStackTags fetches the stack's existing tags.
|
|
|
|
func GetStackTags(ctx context.Context, s Stack) (map[apitype.StackTagName]string, error) {
|
2019-10-14 23:30:42 +02:00
|
|
|
return s.Backend().GetStackTags(ctx, s)
|
2019-01-04 22:23:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// UpdateStackTags updates the stacks's tags, replacing all existing tags.
|
|
|
|
func UpdateStackTags(ctx context.Context, s Stack, tags map[apitype.StackTagName]string) error {
|
2019-10-14 23:30:42 +02:00
|
|
|
return s.Backend().UpdateStackTags(ctx, s, tags)
|
2019-01-04 22:23:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetMergedStackTags returns the stack's existing tags merged with fresh tags from the environment
|
|
|
|
// and Pulumi.yaml file.
|
|
|
|
func GetMergedStackTags(ctx context.Context, s Stack) (map[apitype.StackTagName]string, error) {
|
|
|
|
// Get the stack's existing tags.
|
|
|
|
tags, err := GetStackTags(ctx, s)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if tags == nil {
|
|
|
|
tags = make(map[apitype.StackTagName]string)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get latest environment tags for the current stack.
|
|
|
|
envTags, err := GetEnvironmentTagsForCurrentStack()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add each new environment tag to the existing tags, overwriting existing tags with the
|
|
|
|
// latest values.
|
|
|
|
for k, v := range envTags {
|
|
|
|
tags[k] = v
|
|
|
|
}
|
|
|
|
|
|
|
|
return tags, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetEnvironmentTagsForCurrentStack returns the set of tags for the "current" stack, based on the environment
|
2018-04-11 19:08:32 +02:00
|
|
|
// and Pulumi.yaml file.
|
2019-01-04 22:23:47 +01:00
|
|
|
func GetEnvironmentTagsForCurrentStack() (map[apitype.StackTagName]string, error) {
|
2018-04-11 19:08:32 +02:00
|
|
|
tags := make(map[apitype.StackTagName]string)
|
|
|
|
|
|
|
|
// Tags based on Pulumi.yaml.
|
|
|
|
projPath, err := workspace.DetectProjectPath()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if projPath != "" {
|
|
|
|
proj, err := workspace.LoadProject(projPath)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrapf(err, "error loading project %q", projPath)
|
|
|
|
}
|
|
|
|
tags[apitype.ProjectNameTag] = proj.Name.String()
|
2018-11-01 16:28:11 +01:00
|
|
|
tags[apitype.ProjectRuntimeTag] = proj.Runtime.Name()
|
2018-04-11 19:08:32 +02:00
|
|
|
if proj.Description != nil {
|
|
|
|
tags[apitype.ProjectDescriptionTag] = *proj.Description
|
|
|
|
}
|
2018-05-22 01:17:12 +02:00
|
|
|
|
2018-10-23 23:53:52 +02:00
|
|
|
// Add the git metadata to the tags, ignoring any errors that come from it.
|
|
|
|
ignoredErr := addGitMetadataToStackTags(tags, projPath)
|
|
|
|
contract.IgnoreError(ignoredErr)
|
2018-04-11 19:08:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return tags, nil
|
|
|
|
}
|
|
|
|
|
2018-10-23 23:53:52 +02:00
|
|
|
// addGitMetadataToStackTags fetches the git repository from the directory, and attempts to detect
|
|
|
|
// and add any relevant git metadata as stack tags.
|
|
|
|
func addGitMetadataToStackTags(tags map[apitype.StackTagName]string, projPath string) error {
|
|
|
|
repo, err := gitutil.GetGitRepository(filepath.Dir(projPath))
|
|
|
|
if repo == nil {
|
|
|
|
return fmt.Errorf("no git repository found from %v", projPath)
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
remoteURL, err := gitutil.GetGitRemoteURL(repo, "origin")
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if remoteURL == "" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if vcsInfo, err := gitutil.TryGetVCSInfo(remoteURL); err == nil {
|
|
|
|
tags[apitype.VCSOwnerNameTag] = vcsInfo.Owner
|
|
|
|
tags[apitype.VCSRepositoryNameTag] = vcsInfo.Repo
|
|
|
|
tags[apitype.VCSRepositoryKindTag] = vcsInfo.Kind
|
|
|
|
} else {
|
|
|
|
return errors.Wrapf(err, "detecting VCS info for stack tags for remote %v", remoteURL)
|
|
|
|
}
|
|
|
|
// Set the old stack tags keys as GitHub so that the UI will continue to work,
|
|
|
|
// regardless of whether the remote URL is a GitHub URL or not.
|
|
|
|
// TODO remove these when the UI no longer needs them.
|
|
|
|
if tags[apitype.VCSOwnerNameTag] != "" {
|
|
|
|
tags[apitype.GitHubOwnerNameTag] = tags[apitype.VCSOwnerNameTag]
|
|
|
|
tags[apitype.GitHubRepositoryNameTag] = tags[apitype.VCSRepositoryNameTag]
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|