Merge branch 'master' of https://github.com/pulumi/pulumi into evan/auto
This commit is contained in:
commit
463c7b6588
29
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
29
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: needs-triage
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--- Provide a general summary of the issue -->
|
||||
|
||||
## Expected Behavior
|
||||
<!--- Tell us what should happen -->
|
||||
|
||||
## Current Behavior
|
||||
<!--- Tell us what happens instead of the expected behavior -->
|
||||
|
||||
## Steps to Reproduce
|
||||
<!--- Provide a link to a live example, or an unambiguous set of steps to -->
|
||||
<!--- reproduce this bug. Include code to reproduce, if relevant -->
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4.
|
||||
|
||||
## Context (Environment)
|
||||
<!--- How has this issue affected you? What are you trying to accomplish? -->
|
||||
<!--- Providing context helps us come up with a solution that is most useful in the real world -->
|
||||
<!--- Provide a general summary of the issue in the Title above -->
|
26
.github/workflows/codegen-test.yml
vendored
26
.github/workflows/codegen-test.yml
vendored
|
@ -4,6 +4,8 @@ on:
|
|||
paths:
|
||||
- 'pkg/codegen/**'
|
||||
- '.github/workflows/codegen-test.yml'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
jobs:
|
||||
downstream-aws:
|
||||
|
@ -24,6 +26,10 @@ jobs:
|
|||
python-version: 3.6.11
|
||||
- name: Install Pulumi CLI
|
||||
uses: pulumi/action-install-pulumi-cli@releases/v1
|
||||
- name: Install pulumictl
|
||||
uses: jaxxstorm/action-install-gh-release@release/v1-alpha
|
||||
with:
|
||||
repo: pulumi/pulumictl
|
||||
|
||||
- name: Check out source code
|
||||
uses: actions/checkout@master
|
||||
|
@ -57,6 +63,10 @@ jobs:
|
|||
python-version: 3.6.11
|
||||
- name: Install Pulumi CLI
|
||||
uses: pulumi/action-install-pulumi-cli@releases/v1
|
||||
- name: Install pulumictl
|
||||
uses: jaxxstorm/action-install-gh-release@release/v1-alpha
|
||||
with:
|
||||
repo: pulumi/pulumictl
|
||||
|
||||
- name: Check out source code
|
||||
uses: actions/checkout@master
|
||||
|
@ -90,6 +100,10 @@ jobs:
|
|||
python-version: 3.6.11
|
||||
- name: Install Pulumi CLI
|
||||
uses: pulumi/action-install-pulumi-cli@releases/v1
|
||||
- name: Install pulumictl
|
||||
uses: jaxxstorm/action-install-gh-release@release/v1-alpha
|
||||
with:
|
||||
repo: pulumi/pulumictl
|
||||
|
||||
- name: Check out source code
|
||||
uses: actions/checkout@master
|
||||
|
@ -123,6 +137,10 @@ jobs:
|
|||
python-version: 3.6.11
|
||||
- name: Install Pulumi CLI
|
||||
uses: pulumi/action-install-pulumi-cli@releases/v1
|
||||
- name: Install pulumictl
|
||||
uses: jaxxstorm/action-install-gh-release@release/v1-alpha
|
||||
with:
|
||||
repo: pulumi/pulumictl
|
||||
|
||||
- name: Check out source code
|
||||
uses: actions/checkout@master
|
||||
|
@ -156,6 +174,10 @@ jobs:
|
|||
python-version: 3.6.11
|
||||
- name: Install Pulumi CLI
|
||||
uses: pulumi/action-install-pulumi-cli@releases/v1
|
||||
- name: Install pulumictl
|
||||
uses: jaxxstorm/action-install-gh-release@release/v1-alpha
|
||||
with:
|
||||
repo: pulumi/pulumictl
|
||||
|
||||
- name: Check out source code
|
||||
uses: actions/checkout@master
|
||||
|
@ -189,6 +211,10 @@ jobs:
|
|||
python-version: 3.6.11
|
||||
- name: Install Pulumi CLI
|
||||
uses: pulumi/action-install-pulumi-cli@releases/v1
|
||||
- name: Install pulumictl
|
||||
uses: jaxxstorm/action-install-gh-release@release/v1-alpha
|
||||
with:
|
||||
repo: pulumi/pulumictl
|
||||
|
||||
- name: Check out source code
|
||||
uses: actions/checkout@master
|
||||
|
|
21
.github/workflows/homebrew-bump.yml
vendored
Normal file
21
.github/workflows/homebrew-bump.yml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.PULUMI_BOT_TOKEN }}
|
||||
VERSION: ${{ github.event.client_payload.ref }}
|
||||
COMMIT_SHA: ${{ github.event.client_payload.commitSha }}
|
||||
|
||||
on:
|
||||
repository_dispatch:
|
||||
types:
|
||||
- homebrew-bump
|
||||
|
||||
jobs:
|
||||
homebrew:
|
||||
name: Bump Homebrew formula
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dawidd6/action-homebrew-bump-formula@v3
|
||||
with:
|
||||
token: ${{secrets.GITHUB_TOKEN}}
|
||||
formula: pulumi
|
||||
tag: ${{env.VERSION}}
|
||||
revision: ${{env.COMMIT_SHA}}
|
2
.github/workflows/windows-build.yml
vendored
2
.github/workflows/windows-build.yml
vendored
|
@ -44,7 +44,7 @@ jobs:
|
|||
run: |
|
||||
echo "::set-env name=PULUMI_TEST_OWNER::moolumi"
|
||||
echo "::set-env name=PULUMI_LOCAL_NUGET::D:\\Pulumi\\nuget"
|
||||
echo "::set-env name=PULUMI_ACCESS_TOKEN::${{ secrets.PULUMI_ACCESS_TOKEN }}"
|
||||
echo "::set-env name=PULUMI_API::https://api.pulumi-staging.io"
|
||||
echo "::set-env name=PULUMI_ACCESS_TOKEN::${{ secrets.PULUMI_ACCESS_TOKEN }}"
|
||||
echo "::add-path::D:\\Pulumi\\bin"
|
||||
- name: Install AWS CLI Tools
|
||||
|
|
2
.github/workflows/windows-pr.yml
vendored
2
.github/workflows/windows-pr.yml
vendored
|
@ -40,7 +40,7 @@ jobs:
|
|||
run: |
|
||||
echo "::set-env name=PULUMI_TEST_OWNER::moolumi"
|
||||
echo "::set-env name=PULUMI_LOCAL_NUGET::D:\\Pulumi\\nuget"
|
||||
echo "::set-env name=PULUMI_ACCESS_TOKEN::${{ secrets.PULUMI_ACCESS_TOKEN }}"
|
||||
echo "::set-env name=PULUMI_API::https://api.pulumi-staging.io"
|
||||
echo "::set-env name=PULUMI_ACCESS_TOKEN::${{ secrets.PULUMI_ACCESS_TOKEN }}"
|
||||
echo "::add-path::D:\\Pulumi\\bin"
|
||||
- name: Set AWS Env Vars
|
||||
|
|
77
CHANGELOG.md
77
CHANGELOG.md
|
@ -2,12 +2,87 @@ CHANGELOG
|
|||
=========
|
||||
|
||||
## HEAD (Unreleased)
|
||||
_(none)
|
||||
|
||||
## 2.9.0 (2020-08-19)
|
||||
|
||||
- Fix support for CheckFailures in Python Dynamic Providers
|
||||
[#5138](https://github.com/pulumi/pulumi/pull/5138)
|
||||
|
||||
- Upgrade version of `gocloud.dev`. This ensures that 'AWSKMS' secrets
|
||||
providers can now be used with full ARNs rather than just Aliases
|
||||
[#5138](https://github.com/pulumi/pulumi/pull/5138)
|
||||
|
||||
- Ensure the 'history' command is a subcommand of 'stack'.
|
||||
This means that `pulumi history` has been deprecated in favour
|
||||
of `pulumi stack history`.
|
||||
[#5158](https://github.com/pulumi/pulumi/pull/5158)
|
||||
|
||||
- Add support for extracting jar files in archive resources
|
||||
[#5150](https://github.com/pulumi/pulumi/pull/5150)
|
||||
|
||||
- SDK changes to support Python input/output classes
|
||||
[#5033](https://github.com/pulumi/pulumi/pull/5033)
|
||||
|
||||
## 2.8.2 (2020-08-07)
|
||||
|
||||
- Add nuget badge to README [#5117](https://github.com/pulumi/pulumi/pull/5117)
|
||||
|
||||
- Support publishing and consuming Policy Packs using any runtime
|
||||
[#5102](https://github.com/pulumi/pulumi/pull/5102)
|
||||
|
||||
- Fix regression where any CLI integration for any stack with a default
|
||||
secrets provider would sort the config alphabetically and new stacks created
|
||||
would get created with an empty map `{}` in the config file
|
||||
[#5132](https://github.com/pulumi/pulumi/pull/5132)
|
||||
|
||||
|
||||
## 2.8.1 (2020-08-05)
|
||||
|
||||
- Fix a bug where passphrase managers were not being
|
||||
recognised correctly when getting the configuration
|
||||
for the current stack.
|
||||
**Please Note:**
|
||||
This specific bug may have caused the stack config
|
||||
file to remove the password encryption salt.
|
||||
[#5110](https://github.com/pulumi/pulumi/pull/5110)
|
||||
|
||||
## 2.8.0 (2020-08-04)
|
||||
|
||||
- Add missing MapMap and ArrayArray types to Go SDK
|
||||
[#5092](https://github.com/pulumi/pulumi/pull/5092)
|
||||
|
||||
- Switch os/user package with luser drop in replacement
|
||||
[#5065](https://github.com/pulumi/pulumi/pull/5065)
|
||||
|
||||
- Update pip/setuptools/wheel in virtual environment before installing dependencies
|
||||
[#5042](https://github.com/pulumi/pulumi/pull/5042)
|
||||
|
||||
- Add ability to change a secrets provider for the current stack
|
||||
[#5031](https://github.com/pulumi/pulumi/pull/5031)
|
||||
|
||||
- Add ability to create a stack based on the config from an existing stack
|
||||
[#5062](https://github.com/pulumi/pulumi/pull/5062)
|
||||
|
||||
- Python: Improved error message when `virtualenv` doesn't exist
|
||||
[#5069](https://github.com/pulumi/pulumi/pull/5069)
|
||||
|
||||
- Enable pushing to Artifact Registry in actions
|
||||
[#5075](https://github.com/pulumi/pulumi/pull/5075)
|
||||
|
||||
## 2.7.1 (2020-07-22)
|
||||
|
||||
- Fix logic to parse pulumi venv on github action
|
||||
[5038](https://github.com/pulumi/pulumi/pull/5038)
|
||||
|
||||
## 2.7.0 (2020-07-22)
|
||||
|
||||
- Add pluginDownloadURL field to package definition
|
||||
[#4947](https://github.com/pulumi/pulumi/pull/4947)
|
||||
|
||||
- Add support for streamInvoke during update
|
||||
[#4990](https://github.com/pulumi/pulumi/pull/4990)
|
||||
|
||||
|
||||
- Add ability to copy configuration values between stacks
|
||||
[#4971](https://github.com/pulumi/pulumi/pull/4971)
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
[![Slack](http://www.pulumi.com/images/docs/badges/slack.svg)](https://slack.pulumi.com?utm_campaign=pulumi-pulumi-github-repo&utm_source=github.com&utm_medium=slack-badge)
|
||||
[![NPM version](https://badge.fury.io/js/%40pulumi%2Fpulumi.svg)](https://npmjs.com/package/@pulumi/pulumi)
|
||||
[![Python version](https://badge.fury.io/py/pulumi.svg)](https://pypi.org/project/pulumi)
|
||||
[![NuGet version](https://badge.fury.io/nu/pulumi.svg)](https://badge.fury.io/nu/pulumi)
|
||||
[![GoDoc](https://godoc.org/github.com/pulumi/pulumi?status.svg)](https://godoc.org/github.com/pulumi/pulumi)
|
||||
[![License](https://img.shields.io/npm/l/%40pulumi%2Fpulumi.svg)](https://github.com/pulumi/pulumi/blob/master/LICENSE)
|
||||
|
||||
|
|
6
dist/actions/entrypoint.sh
vendored
6
dist/actions/entrypoint.sh
vendored
|
@ -88,7 +88,7 @@ if [ ! -z "$GOOGLE_CREDENTIALS" ]; then
|
|||
echo "$GOOGLE_CREDENTIALS" > $GOOGLE_APPLICATION_CREDENTIALS
|
||||
fi
|
||||
gcloud auth activate-service-account --key-file=$GOOGLE_APPLICATION_CREDENTIALS
|
||||
gcloud --quiet auth configure-docker
|
||||
gcloud --quiet auth configure-docker $GOOGLE_DOCKER_HOSTNAME_LIST
|
||||
fi
|
||||
|
||||
# Next, run npm install. We always call this, as
|
||||
|
@ -121,12 +121,12 @@ if [ -e requirements.txt ]; then
|
|||
# Check if should use venv
|
||||
PULUMI_VENV=$(cat Pulumi.yaml | grep "virtualenv:" | cut -d':' -f2)
|
||||
if [ -z $PULUMI_VENV ]; then
|
||||
pip3 install -r requirements.txt
|
||||
else
|
||||
python3 -m venv $PULUMI_VENV
|
||||
source $PULUMI_VENV/bin/activate
|
||||
pip3 install -r requirements.txt
|
||||
deactivate
|
||||
else
|
||||
pip3 install -r requirements.txt
|
||||
fi
|
||||
fi
|
||||
|
||||
|
|
|
@ -18,9 +18,9 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
user "github.com/tweekmonster/luser"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/user"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package filestate
|
||||
|
||||
import (
|
||||
"os/user"
|
||||
user "github.com/tweekmonster/luser"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
|
|
@ -185,19 +185,15 @@ func (pack *cloudPolicyPack) Publish(
|
|||
return result.FromError(
|
||||
errors.Wrap(err, "could not publish policies because of error running npm pack"))
|
||||
}
|
||||
} else if strings.EqualFold(runtime, "python") {
|
||||
} else {
|
||||
// npm pack puts all the files in a "package" subdirectory inside the .tgz it produces, so we'll do
|
||||
// the same for Python. That way, after unpacking, we can look for the PulumiPolicy.yaml inside the
|
||||
// the same for other runtimes. That way, after unpacking, we can look for the PulumiPolicy.yaml inside the
|
||||
// package directory to determine the runtime of the policy pack.
|
||||
packTarball, err = archive.TGZ(op.PlugCtx.Pwd, "package", true /*useDefaultExcludes*/)
|
||||
if err != nil {
|
||||
return result.FromError(
|
||||
errors.Wrap(err, "could not publish policies because of error creating the .tgz"))
|
||||
}
|
||||
} else {
|
||||
return result.Errorf(
|
||||
"failed to publish policies because PulumiPolicy.yaml specifies an unsupported runtime %s",
|
||||
runtime)
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -298,12 +294,19 @@ func installRequiredPolicy(finalDir string, tarball []byte) error {
|
|||
|
||||
// TODO[pulumi/pulumi#1334]: move to the language plugins so we don't have to hard code here.
|
||||
if strings.EqualFold(proj.Runtime.Name(), "nodejs") {
|
||||
return completeNodeJSInstall(finalDir)
|
||||
if err := completeNodeJSInstall(finalDir); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if strings.EqualFold(proj.Runtime.Name(), "python") {
|
||||
return completePythonInstall(finalDir, projPath, proj)
|
||||
if err := completePythonInstall(finalDir, projPath, proj); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return errors.Errorf("unsupported policy runtime %s", proj.Runtime.Name())
|
||||
fmt.Println("Finished installing policy pack")
|
||||
fmt.Println()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func completeNodeJSInstall(finalDir string) error {
|
||||
|
@ -314,8 +317,6 @@ func completeNodeJSInstall(finalDir string) error {
|
|||
"in %q before this policy pack works", bin, finalDir)
|
||||
}
|
||||
|
||||
fmt.Println("Finished installing policy pack")
|
||||
fmt.Println()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -331,7 +332,5 @@ func completePythonInstall(finalDir, projPath string, proj *workspace.PolicyPack
|
|||
return err
|
||||
}
|
||||
|
||||
fmt.Println("Finished installing policy pack")
|
||||
fmt.Println()
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -61,11 +61,11 @@ func getStackSecretsManager(s backend.Stack) (secrets.Manager, error) {
|
|||
return newPassphraseSecretsManager(s.Ref().Name(), stackConfigFile)
|
||||
}
|
||||
|
||||
switch stack := s.(type) {
|
||||
case httpstate.Stack:
|
||||
return newServiceSecretsManager(stack)
|
||||
switch s.(type) {
|
||||
case filestate.Stack:
|
||||
return newPassphraseSecretsManager(s.Ref().Name(), stackConfigFile)
|
||||
case httpstate.Stack:
|
||||
return newServiceSecretsManager(s.(httpstate.Stack), s.Ref().Name(), stackConfigFile)
|
||||
}
|
||||
|
||||
return nil, errors.Errorf("unknown stack type %s", reflect.TypeOf(s))
|
||||
|
|
|
@ -18,11 +18,69 @@ import (
|
|||
"github.com/pulumi/pulumi/pkg/v2/backend/httpstate"
|
||||
"github.com/pulumi/pulumi/pkg/v2/secrets"
|
||||
"github.com/pulumi/pulumi/pkg/v2/secrets/service"
|
||||
"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/workspace"
|
||||
)
|
||||
|
||||
func newServiceSecretsManager(s httpstate.Stack) (secrets.Manager, error) {
|
||||
func newServiceSecretsManager(s httpstate.Stack, stackName tokens.QName, configFile string) (secrets.Manager, error) {
|
||||
contract.Assertf(stackName != "", "stackName %s", "!= \"\"")
|
||||
|
||||
if configFile == "" {
|
||||
f, err := workspace.DetectProjectStackPath(stackName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
configFile = f
|
||||
}
|
||||
|
||||
info, err := workspace.LoadProjectStack(configFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client := s.Backend().(httpstate.Backend).Client()
|
||||
id := s.StackIdentifier()
|
||||
|
||||
// We should only save the ProjectStack at this point IF we have changed the
|
||||
// secrets provider. To change the secrets provider to a serviceSecretsManager
|
||||
// we would need to ensure that there are no remnants of the old secret manager
|
||||
// To remove those remnants, we would set those values to be empty in the project
|
||||
// stack, as per changeProjectStackSecretDetails func.
|
||||
// If we do not check to see if the secrets provider has changed, then we will actually
|
||||
// reload the configuration file to be sorted or an empty {} when creating a stack
|
||||
// this is not the desired behaviour.
|
||||
if changeProjectStackSecretDetails(info) {
|
||||
if err := workspace.SaveProjectStack(stackName, info); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return service.NewServiceSecretsManager(client, id)
|
||||
}
|
||||
|
||||
// A passphrase secrets provider has an encryption salt, therefore, changing
|
||||
// from passphrase to serviceSecretsManager requires the encryption salt
|
||||
// to be removed.
|
||||
// A cloud secrets manager has an encryption key and a secrets provider,
|
||||
// therefore, changing from cloud to serviceSecretsManager requires the
|
||||
// encryption key and secrets provider to be removed.
|
||||
// Regardless of what the current secrets provider is, all of these values
|
||||
// need to be empty otherwise `getStackSecretsManager` in crypto.go can
|
||||
// potentially return the incorrect secret type for the stack.
|
||||
func changeProjectStackSecretDetails(info *workspace.ProjectStack) bool {
|
||||
var requiresSave bool
|
||||
if info.SecretsProvider != "" {
|
||||
info.SecretsProvider = ""
|
||||
requiresSave = true
|
||||
}
|
||||
if info.EncryptedKey != "" {
|
||||
info.EncryptedKey = ""
|
||||
requiresSave = true
|
||||
}
|
||||
if info.EncryptionSalt != "" {
|
||||
info.EncryptionSalt = ""
|
||||
requiresSave = true
|
||||
}
|
||||
return requiresSave
|
||||
}
|
||||
|
|
49
pkg/cmd/pulumi/crypto_http_test.go
Normal file
49
pkg/cmd/pulumi/crypto_http_test.go
Normal file
|
@ -0,0 +1,49 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/resource/config"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/workspace"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestChangeProjectStackSecretDetails(t *testing.T) {
|
||||
tests := []struct {
|
||||
TestName string
|
||||
ProjectStack workspace.ProjectStack
|
||||
Expected bool
|
||||
}{
|
||||
{
|
||||
TestName: "Expects to save stack when existing secrets manager is cloud",
|
||||
ProjectStack: workspace.ProjectStack{
|
||||
Config: make(config.Map),
|
||||
SecretsProvider: "awskms://alias/TestProvider?region=us-west-2",
|
||||
EncryptedKey: "AQICAHhAA+FYp21DcGwS7xUizcOsoZihxKtWVCjZpgsK7owkfQF3sftIrKkJOJ0VYq69rHxvAAAAfjB8Bgkqhk",
|
||||
},
|
||||
Expected: true,
|
||||
},
|
||||
{
|
||||
TestName: "Expects to save stack when existing secrets manager is passphrase",
|
||||
ProjectStack: workspace.ProjectStack{
|
||||
Config: make(config.Map),
|
||||
EncryptionSalt: "v1:/AQICAHhAA+FYp21DcGwS7xUizcOsoZihxKtWVCjZpgsK7owkfQF3sftIrKkJOJ0VYq69rHxvAAAAfjB8Bgkqhk",
|
||||
},
|
||||
Expected: true,
|
||||
},
|
||||
{
|
||||
TestName: "Does not expect to save stack when existing secrets manager is service",
|
||||
ProjectStack: workspace.ProjectStack{
|
||||
Config: make(config.Map),
|
||||
},
|
||||
Expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.TestName, func(t *testing.T) {
|
||||
requiresProjectSave := changeProjectStackSecretDetails(&test.ProjectStack)
|
||||
assert.Equal(t, test.Expected, requiresProjectSave)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -15,24 +15,15 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/pulumi/pulumi/pkg/v2/backend"
|
||||
"github.com/pulumi/pulumi/pkg/v2/backend/display"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/diag/colors"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/resource/config"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/util/cmdutil"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/util/contract"
|
||||
)
|
||||
|
||||
// TO-DO: Remove as part of Pulumi v3.0.0
|
||||
func newHistoryCmd() *cobra.Command {
|
||||
var stack string
|
||||
var jsonOut bool
|
||||
|
@ -41,10 +32,12 @@ func newHistoryCmd() *cobra.Command {
|
|||
Use: "history",
|
||||
Aliases: []string{"hist"},
|
||||
SuggestFor: []string{"updates"},
|
||||
Short: "[PREVIEW] Update history for a stack",
|
||||
Long: `Update history for a stack
|
||||
|
||||
This command lists data about previous updates for a stack.`,
|
||||
Hidden: true,
|
||||
Short: "[DEPRECATED] Display history for a stack",
|
||||
Long: "Display history for a stack.\n\n" +
|
||||
"This command displays data about previous updates for a stack.\n\n" +
|
||||
"This command is now DEPRECATED, please use `pulumi stack history`.\n" +
|
||||
"The command will be removed in a future release",
|
||||
Args: cmdutil.NoArgs,
|
||||
Run: cmdutil.RunFunc(func(cmd *cobra.Command, args []string) error {
|
||||
opts := display.Options{
|
||||
|
@ -85,123 +78,3 @@ This command lists data about previous updates for a stack.`,
|
|||
&jsonOut, "json", "j", false, "Emit output as JSON")
|
||||
return cmd
|
||||
}
|
||||
|
||||
// updateInfoJSON is the shape of the --json output for a configuration value. While we can add fields to this
|
||||
// structure in the future, we should not change existing fields.
|
||||
type updateInfoJSON struct {
|
||||
Kind string `json:"kind"`
|
||||
StartTime string `json:"startTime"`
|
||||
Message string `json:"message"`
|
||||
Environment map[string]string `json:"environment"`
|
||||
Config map[string]configValueJSON `json:"config"`
|
||||
Result string `json:"result,omitempty"`
|
||||
|
||||
// These values are only present once the update finishes
|
||||
EndTime *string `json:"endTime,omitempty"`
|
||||
ResourceChanges *map[string]int `json:"resourceChanges,omitempty"`
|
||||
}
|
||||
|
||||
func displayUpdatesJSON(updates []backend.UpdateInfo, decrypter config.Decrypter) error {
|
||||
makeStringRef := func(s string) *string {
|
||||
return &s
|
||||
}
|
||||
|
||||
updatesJSON := make([]updateInfoJSON, len(updates))
|
||||
for idx, update := range updates {
|
||||
info := updateInfoJSON{
|
||||
Kind: string(update.Kind),
|
||||
StartTime: time.Unix(update.StartTime, 0).UTC().Format(timeFormat),
|
||||
Message: update.Message,
|
||||
Environment: update.Environment,
|
||||
}
|
||||
|
||||
info.Config = make(map[string]configValueJSON)
|
||||
for k, v := range update.Config {
|
||||
configValue := configValueJSON{
|
||||
Secret: v.Secure(),
|
||||
}
|
||||
if !v.Secure() || (v.Secure() && decrypter != nil) {
|
||||
value, err := v.Value(decrypter)
|
||||
contract.AssertNoError(err)
|
||||
configValue.Value = makeStringRef(value)
|
||||
|
||||
if v.Object() {
|
||||
var obj interface{}
|
||||
if err := json.Unmarshal([]byte(value), &obj); err != nil {
|
||||
return err
|
||||
}
|
||||
configValue.ObjectValue = obj
|
||||
}
|
||||
}
|
||||
|
||||
info.Config[k.String()] = configValue
|
||||
}
|
||||
info.Result = string(update.Result)
|
||||
if update.Result != backend.InProgressResult {
|
||||
info.EndTime = makeStringRef(time.Unix(update.EndTime, 0).UTC().Format(timeFormat))
|
||||
resourceChanges := make(map[string]int)
|
||||
for k, v := range update.ResourceChanges {
|
||||
resourceChanges[string(k)] = v
|
||||
}
|
||||
info.ResourceChanges = &resourceChanges
|
||||
}
|
||||
updatesJSON[idx] = info
|
||||
}
|
||||
|
||||
return printJSON(updatesJSON)
|
||||
}
|
||||
|
||||
func displayUpdatesConsole(updates []backend.UpdateInfo, opts display.Options) error {
|
||||
if len(updates) == 0 {
|
||||
fmt.Println("Stack has never been updated")
|
||||
return nil
|
||||
}
|
||||
|
||||
printResourceChanges := func(background, text, sign, reset string, amount int) {
|
||||
msg := opts.Color.Colorize(fmt.Sprintf("%s%s%s%v%s", background, text, sign, amount, reset))
|
||||
fmt.Print(msg)
|
||||
}
|
||||
|
||||
for _, update := range updates {
|
||||
|
||||
fmt.Printf("UpdateKind: %v\n", update.Kind)
|
||||
if update.Result == "succeeded" {
|
||||
fmt.Print(opts.Color.Colorize(fmt.Sprintf("%sStatus: %v%s\n", colors.Green, update.Result, colors.Reset)))
|
||||
} else {
|
||||
fmt.Print(opts.Color.Colorize(fmt.Sprintf("%sStatus: %v%s\n", colors.Red, update.Result, colors.Reset)))
|
||||
}
|
||||
fmt.Printf("Message: %v\n", update.Message)
|
||||
|
||||
printResourceChanges(colors.GreenBackground, colors.Black, "+", colors.Reset, update.ResourceChanges["create"])
|
||||
printResourceChanges(colors.RedBackground, colors.Black, "-", colors.Reset, update.ResourceChanges["delete"])
|
||||
printResourceChanges(colors.YellowBackground, colors.Black, "~", colors.Reset, update.ResourceChanges["update"])
|
||||
printResourceChanges(colors.BlueBackground, colors.Black, " ", colors.Reset, update.ResourceChanges["same"])
|
||||
|
||||
timeStart := time.Unix(update.StartTime, 0)
|
||||
timeCreated := humanize.Time(timeStart)
|
||||
timeEnd := time.Unix(update.EndTime, 0)
|
||||
duration := timeEnd.Sub(timeStart)
|
||||
fmt.Printf("%sUpdated %s took %s\n", " ", timeCreated, duration)
|
||||
|
||||
isEmpty := func(s string) bool {
|
||||
return len(strings.TrimSpace(s)) == 0
|
||||
}
|
||||
var keys []string
|
||||
for k := range update.Environment {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
indent := 4
|
||||
for _, k := range keys {
|
||||
if k == backend.GitHead && !isEmpty(update.Environment[k]) {
|
||||
fmt.Print(opts.Color.Colorize(
|
||||
fmt.Sprintf("%*s%s%s: %s%s\n", indent, "", colors.Yellow, k, update.Environment[k], colors.Reset)))
|
||||
} else if !isEmpty(update.Environment[k]) {
|
||||
fmt.Printf("%*s%s: %s\n", indent, "", k, update.Environment[k])
|
||||
}
|
||||
}
|
||||
fmt.Println("")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -751,8 +751,11 @@ func pythonCommands() []string {
|
|||
commands = append(commands, "source venv/bin/activate")
|
||||
}
|
||||
|
||||
// Install dependencies within the virtualenv
|
||||
commands = append(commands, "pip3 install -r requirements.txt")
|
||||
// Update pip, setuptools, and wheel within the virtualenv.
|
||||
commands = append(commands, "python -m pip install --upgrade pip setuptools wheel")
|
||||
|
||||
// Install dependencies within the virtualenv.
|
||||
commands = append(commands, "python -m pip install -r requirements.txt")
|
||||
|
||||
return commands
|
||||
}
|
||||
|
|
|
@ -19,11 +19,11 @@ import (
|
|||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
user "github.com/tweekmonster/luser"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
|
|
|
@ -179,6 +179,8 @@ func newStackCmd() *cobra.Command {
|
|||
cmd.AddCommand(newStackSelectCmd())
|
||||
cmd.AddCommand(newStackTagCmd())
|
||||
cmd.AddCommand(newStackRenameCmd())
|
||||
cmd.AddCommand(newStackChangeSecretsProviderCmd())
|
||||
cmd.AddCommand(newStackHistoryCmd())
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
|
177
pkg/cmd/pulumi/stack_change_secrets_provider.go
Normal file
177
pkg/cmd/pulumi/stack_change_secrets_provider.go
Normal file
|
@ -0,0 +1,177 @@
|
|||
// Copyright 2016-2020, 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.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pulumi/pulumi/pkg/v2/backend"
|
||||
"github.com/pulumi/pulumi/pkg/v2/resource/stack"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/apitype"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/resource/config"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/pulumi/pulumi/pkg/v2/backend/display"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/util/cmdutil"
|
||||
)
|
||||
|
||||
func newStackChangeSecretsProviderCmd() *cobra.Command {
|
||||
var cmd = &cobra.Command{
|
||||
Use: "change-secrets-provider <new-secrets-provider>",
|
||||
Args: cmdutil.ExactArgs(1),
|
||||
Short: "Change the secrets provider for the current stack",
|
||||
Long: "Change the secrets provider for the current stack. " +
|
||||
"Valid secret providers types are `default`, `passphrase`, `awskms`, `azurekeyvault`, `gcpkms`, `hashivault`.\n\n" +
|
||||
"To change to using the Pulumi Default Secrets Provider, use the following:\n" +
|
||||
"\n" +
|
||||
"pulumi stack change-secrets-provider default" +
|
||||
"\n" +
|
||||
"\n" +
|
||||
"To change the stack to use a cloud secrets backend, use one of the following:\n" +
|
||||
"\n" +
|
||||
"* `pulumi stack change-secrets-provider \"awskms://alias/ExampleAlias?region=us-east-1\"" +
|
||||
"`\n" +
|
||||
"* `pulumi stack change-secrets-provider " +
|
||||
"\"awskms://1234abcd-12ab-34cd-56ef-1234567890ab?region=us-east-1\"`\n" +
|
||||
"* `pulumi stack change-secrets-provider " +
|
||||
"\"azurekeyvault://mykeyvaultname.vault.azure.net/keys/mykeyname\"`\n" +
|
||||
"* `pulumi stack change-secrets-provider " +
|
||||
"\"gcpkms://projects/<p>/locations/<l>/keyRings/<r>/cryptoKeys/<k>\"`\n" +
|
||||
"* `pulumi stack change-secrets-provider \"hashivault://mykey\"`",
|
||||
Run: cmdutil.RunFunc(func(cmd *cobra.Command, args []string) error {
|
||||
opts := display.Options{
|
||||
Color: cmdutil.GetGlobalColorization(),
|
||||
}
|
||||
|
||||
// Validate secrets provider type
|
||||
if err := validateSecretsProvider(args[0]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the current backend
|
||||
b, err := currentBackend(opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the current stack and its project
|
||||
currentStack, err := requireStack("", false, opts, true /*setCurrent*/)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
currentProjectStack, err := loadProjectStack(currentStack)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Build decrypter based on the existing secrets provider
|
||||
var decrypter config.Decrypter
|
||||
currentConfig := currentProjectStack.Config
|
||||
|
||||
if currentConfig.HasSecureValue() {
|
||||
dec, decerr := getStackDecrypter(currentStack)
|
||||
if decerr != nil {
|
||||
return decerr
|
||||
}
|
||||
decrypter = dec
|
||||
} else {
|
||||
decrypter = config.NewPanicCrypter()
|
||||
}
|
||||
|
||||
// Create the new secrets provider and set to the currentStack
|
||||
if err := createSecretsManager(b, currentStack.Ref(), args[0]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Change the config to use the new secrets provider
|
||||
err = migrateConfigToNewSecretsProvider(currentStack, currentConfig, decrypter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Fixup the checkpoint
|
||||
return migrateCheckpointToNewSecretsProvider(commandContext(), currentStack)
|
||||
}),
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func migrateCheckpointToNewSecretsProvider(ctx context.Context, currentStack backend.Stack) error {
|
||||
// Load the current checkpoint so those secrets can also be decrypted
|
||||
checkpoint, err := currentStack.ExportDeployment(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
snap, err := stack.DeserializeUntypedDeployment(checkpoint, stack.DefaultSecretsProvider)
|
||||
if err != nil {
|
||||
return checkDeploymentVersionError(err, currentStack.Ref().Name().String())
|
||||
}
|
||||
|
||||
// Get the newly created secrets manager for the stack
|
||||
newSecretsManager, err := getStackSecretsManager(currentStack)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Reserialize the Snapshopshot with the NewSecrets Manager
|
||||
reserializedDeployment, err := stack.SerializeDeployment(snap, newSecretsManager, false /*showSecrets*/)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bytes, err := json.Marshal(reserializedDeployment)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dep := apitype.UntypedDeployment{
|
||||
Version: apitype.DeploymentSchemaVersionCurrent,
|
||||
Deployment: bytes,
|
||||
}
|
||||
|
||||
// Import the newly changes Deployment
|
||||
return currentStack.ImportDeployment(ctx, &dep)
|
||||
}
|
||||
|
||||
func migrateConfigToNewSecretsProvider(currentStack backend.Stack, currentConfig config.Map,
|
||||
decrypter config.Decrypter) error {
|
||||
// Get the new encrypter for the current stack
|
||||
newEncrypter, err := getStackEncrypter(currentStack)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create a copy of the current config map and re-encrypt using the new secrets provider
|
||||
newProjectConfig, err := currentConfig.Copy(decrypter, newEncrypter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Reload the project stack after the new secretsProvider is in place
|
||||
reloadedProjectStack, err := loadProjectStack(currentStack)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for key, val := range newProjectConfig {
|
||||
if err := reloadedProjectStack.Config.Set(key, val, false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return saveProjectStack(currentStack, reloadedProjectStack)
|
||||
}
|
194
pkg/cmd/pulumi/stack_history.go
Normal file
194
pkg/cmd/pulumi/stack_history.go
Normal file
|
@ -0,0 +1,194 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/pulumi/pulumi/pkg/v2/backend"
|
||||
"github.com/pulumi/pulumi/pkg/v2/backend/display"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/diag/colors"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/resource/config"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/util/cmdutil"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/util/contract"
|
||||
)
|
||||
|
||||
func newStackHistoryCmd() *cobra.Command {
|
||||
var stack string
|
||||
var jsonOut bool
|
||||
var showSecrets bool
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "history",
|
||||
Aliases: []string{"hist"},
|
||||
SuggestFor: []string{"updates"},
|
||||
Short: "[PREVIEW] Display history for a stack",
|
||||
Long: `Display history for a stack
|
||||
|
||||
This command displays data about previous updates for a stack.`,
|
||||
Run: cmdutil.RunFunc(func(cmd *cobra.Command, args []string) error {
|
||||
opts := display.Options{
|
||||
Color: cmdutil.GetGlobalColorization(),
|
||||
}
|
||||
s, err := requireStack(stack, false /*offerNew */, opts, false /*setCurrent*/)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b := s.Backend()
|
||||
updates, err := b.GetHistory(commandContext(), s.Ref())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting history")
|
||||
}
|
||||
var decrypter config.Decrypter
|
||||
if showSecrets {
|
||||
crypter, err := getStackDecrypter(s)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "decrypting secrets")
|
||||
}
|
||||
decrypter = crypter
|
||||
}
|
||||
|
||||
if jsonOut {
|
||||
return displayUpdatesJSON(updates, decrypter)
|
||||
}
|
||||
|
||||
return displayUpdatesConsole(updates, opts)
|
||||
}),
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().StringVarP(
|
||||
&stack, "stack", "s", "",
|
||||
"Choose a stack other than the currently selected one")
|
||||
cmd.Flags().BoolVar(
|
||||
&showSecrets, "show-secrets", false,
|
||||
"Show secret values when listing config instead of displaying blinded values")
|
||||
cmd.PersistentFlags().BoolVarP(
|
||||
&jsonOut, "json", "j", false, "Emit output as JSON")
|
||||
return cmd
|
||||
}
|
||||
|
||||
// updateInfoJSON is the shape of the --json output for a configuration value. While we can add fields to this
|
||||
// structure in the future, we should not change existing fields.
|
||||
type updateInfoJSON struct {
|
||||
Kind string `json:"kind"`
|
||||
StartTime string `json:"startTime"`
|
||||
Message string `json:"message"`
|
||||
Environment map[string]string `json:"environment"`
|
||||
Config map[string]configValueJSON `json:"config"`
|
||||
Result string `json:"result,omitempty"`
|
||||
|
||||
// These values are only present once the update finishes
|
||||
EndTime *string `json:"endTime,omitempty"`
|
||||
ResourceChanges *map[string]int `json:"resourceChanges,omitempty"`
|
||||
}
|
||||
|
||||
func displayUpdatesJSON(updates []backend.UpdateInfo, decrypter config.Decrypter) error {
|
||||
makeStringRef := func(s string) *string {
|
||||
return &s
|
||||
}
|
||||
|
||||
updatesJSON := make([]updateInfoJSON, len(updates))
|
||||
for idx, update := range updates {
|
||||
info := updateInfoJSON{
|
||||
Kind: string(update.Kind),
|
||||
StartTime: time.Unix(update.StartTime, 0).UTC().Format(timeFormat),
|
||||
Message: update.Message,
|
||||
Environment: update.Environment,
|
||||
}
|
||||
|
||||
info.Config = make(map[string]configValueJSON)
|
||||
for k, v := range update.Config {
|
||||
configValue := configValueJSON{
|
||||
Secret: v.Secure(),
|
||||
}
|
||||
if !v.Secure() || (v.Secure() && decrypter != nil) {
|
||||
value, err := v.Value(decrypter)
|
||||
contract.AssertNoError(err)
|
||||
configValue.Value = makeStringRef(value)
|
||||
|
||||
if v.Object() {
|
||||
var obj interface{}
|
||||
if err := json.Unmarshal([]byte(value), &obj); err != nil {
|
||||
return err
|
||||
}
|
||||
configValue.ObjectValue = obj
|
||||
}
|
||||
}
|
||||
|
||||
info.Config[k.String()] = configValue
|
||||
}
|
||||
info.Result = string(update.Result)
|
||||
if update.Result != backend.InProgressResult {
|
||||
info.EndTime = makeStringRef(time.Unix(update.EndTime, 0).UTC().Format(timeFormat))
|
||||
resourceChanges := make(map[string]int)
|
||||
for k, v := range update.ResourceChanges {
|
||||
resourceChanges[string(k)] = v
|
||||
}
|
||||
info.ResourceChanges = &resourceChanges
|
||||
}
|
||||
updatesJSON[idx] = info
|
||||
}
|
||||
|
||||
return printJSON(updatesJSON)
|
||||
}
|
||||
|
||||
func displayUpdatesConsole(updates []backend.UpdateInfo, opts display.Options) error {
|
||||
if len(updates) == 0 {
|
||||
fmt.Println("Stack has never been updated")
|
||||
return nil
|
||||
}
|
||||
|
||||
printResourceChanges := func(background, text, sign, reset string, amount int) {
|
||||
msg := opts.Color.Colorize(fmt.Sprintf("%s%s%s%v%s", background, text, sign, amount, reset))
|
||||
fmt.Print(msg)
|
||||
}
|
||||
|
||||
for _, update := range updates {
|
||||
|
||||
fmt.Printf("UpdateKind: %v\n", update.Kind)
|
||||
if update.Result == "succeeded" {
|
||||
fmt.Print(opts.Color.Colorize(fmt.Sprintf("%sStatus: %v%s\n", colors.Green, update.Result, colors.Reset)))
|
||||
} else {
|
||||
fmt.Print(opts.Color.Colorize(fmt.Sprintf("%sStatus: %v%s\n", colors.Red, update.Result, colors.Reset)))
|
||||
}
|
||||
fmt.Printf("Message: %v\n", update.Message)
|
||||
|
||||
printResourceChanges(colors.GreenBackground, colors.Black, "+", colors.Reset, update.ResourceChanges["create"])
|
||||
printResourceChanges(colors.RedBackground, colors.Black, "-", colors.Reset, update.ResourceChanges["delete"])
|
||||
printResourceChanges(colors.YellowBackground, colors.Black, "~", colors.Reset, update.ResourceChanges["update"])
|
||||
printResourceChanges(colors.BlueBackground, colors.Black, " ", colors.Reset, update.ResourceChanges["same"])
|
||||
|
||||
timeStart := time.Unix(update.StartTime, 0)
|
||||
timeCreated := humanize.Time(timeStart)
|
||||
timeEnd := time.Unix(update.EndTime, 0)
|
||||
duration := timeEnd.Sub(timeStart)
|
||||
fmt.Printf("%sUpdated %s took %s\n", " ", timeCreated, duration)
|
||||
|
||||
isEmpty := func(s string) bool {
|
||||
return len(strings.TrimSpace(s)) == 0
|
||||
}
|
||||
var keys []string
|
||||
for k := range update.Environment {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
indent := 4
|
||||
for _, k := range keys {
|
||||
if k == backend.GitHead && !isEmpty(update.Environment[k]) {
|
||||
fmt.Print(opts.Color.Colorize(
|
||||
fmt.Sprintf("%*s%s%s: %s%s\n", indent, "", colors.Yellow, k, update.Environment[k], colors.Reset)))
|
||||
} else if !isEmpty(update.Environment[k]) {
|
||||
fmt.Printf("%*s%s: %s\n", indent, "", k, update.Environment[k])
|
||||
}
|
||||
}
|
||||
fmt.Println("")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -32,6 +32,7 @@ const (
|
|||
func newStackInitCmd() *cobra.Command {
|
||||
var secretsProvider string
|
||||
var stackName string
|
||||
var stackToCopy string
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "init [<org-name>/]<stack-name>",
|
||||
|
@ -60,7 +61,11 @@ func newStackInitCmd() *cobra.Command {
|
|||
"* `pulumi stack init --secrets-provider=\"awskms://1234abcd-12ab-34cd-56ef-1234567890ab?region=us-east-1\"`\n" +
|
||||
"* `pulumi stack init --secrets-provider=\"azurekeyvault://mykeyvaultname.vault.azure.net/keys/mykeyname\"`\n" +
|
||||
"* `pulumi stack init --secrets-provider=\"gcpkms://projects/<p>/locations/<l>/keyRings/<r>/cryptoKeys/<k>\"`\n" +
|
||||
"* `pulumi stack init --secrets-provider=\"hashivault://mykey\"`",
|
||||
"* `pulumi stack init --secrets-provider=\"hashivault://mykey\"\n`" +
|
||||
"\n" +
|
||||
"A stack can be created based on the configuration of an existing stack by passing the\n" +
|
||||
"`--copy-config-from` flag.\n" +
|
||||
"* `pulumi stack init --copy-config-from dev",
|
||||
Run: cmdutil.RunFunc(func(cmd *cobra.Command, args []string) error {
|
||||
opts := display.Options{
|
||||
Color: cmdutil.GetGlobalColorization(),
|
||||
|
@ -112,13 +117,40 @@ func newStackInitCmd() *cobra.Command {
|
|||
}
|
||||
|
||||
var createOpts interface{} // Backend-specific config options, none currently.
|
||||
_, err = createStack(b, stackRef, createOpts, true /*setCurrent*/, secretsProvider)
|
||||
return err
|
||||
newStack, err := createStack(b, stackRef, createOpts, true /*setCurrent*/, secretsProvider)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if stackToCopy != "" {
|
||||
// load the old stack and its project
|
||||
copyStack, err := requireStack(stackToCopy, false, opts, false /*setCurrent*/)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
copyProjectStack, err := loadProjectStack(copyStack)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// get the project for the newly created stack
|
||||
newProjectStack, err := loadProjectStack(newStack)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// copy the config from the old to the new
|
||||
return copyEntireConfigMap(copyStack, copyProjectStack, newStack, newProjectStack)
|
||||
}
|
||||
|
||||
return nil
|
||||
}),
|
||||
}
|
||||
cmd.PersistentFlags().StringVarP(
|
||||
&stackName, "stack", "s", "", "The name of the stack to create")
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&secretsProvider, "secrets-provider", "default", possibleSecretsProviderChoices)
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&stackToCopy, "copy-config-from", "", "The name of the stack to copy existing config from")
|
||||
return cmd
|
||||
}
|
||||
|
|
|
@ -114,11 +114,7 @@ func commandContext() context.Context {
|
|||
return ctx
|
||||
}
|
||||
|
||||
// createStack creates a stack with the given name, and optionally selects it as the current.
|
||||
func createStack(
|
||||
b backend.Backend, stackRef backend.StackReference, opts interface{}, setCurrent bool,
|
||||
secretsProvider string) (backend.Stack, error) {
|
||||
|
||||
func createSecretsManager(b backend.Backend, stackRef backend.StackReference, secretsProvider string) error {
|
||||
// As part of creating the stack, we also need to configure the secrets provider for the stack.
|
||||
// We need to do this configuration step for cases where we will be using with the passphrase
|
||||
// secrets provider or one of the cloud-backed secrets providers. We do not need to do this
|
||||
|
@ -128,9 +124,27 @@ func createStack(
|
|||
// The default when using the filestate backend is the passphrase secrets provider
|
||||
secretsProvider = passphrase.Type
|
||||
}
|
||||
|
||||
if _, ok := b.(httpstate.Backend); ok && isDefaultSecretsProvider {
|
||||
stack, err := state.CurrentStack(commandContext(), b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if stack == nil {
|
||||
// This means this is the first time we are initiating a stack
|
||||
// there is no way a stack will exist here so we need to just return nil
|
||||
// this will mean the "old" default behaviour will work for us
|
||||
return nil
|
||||
}
|
||||
if _, serviceSecretsErr := newServiceSecretsManager(stack.(httpstate.Stack),
|
||||
stackRef.Name(), stackConfigFile); serviceSecretsErr != nil {
|
||||
return serviceSecretsErr
|
||||
}
|
||||
}
|
||||
|
||||
if secretsProvider == passphrase.Type {
|
||||
if _, pharseErr := newPassphraseSecretsManager(stackRef.Name(), stackConfigFile); pharseErr != nil {
|
||||
return nil, pharseErr
|
||||
return pharseErr
|
||||
}
|
||||
} else if !isDefaultSecretsProvider {
|
||||
// All other non-default secrets providers are handled by the cloud secrets provider which
|
||||
|
@ -141,7 +155,7 @@ func createStack(
|
|||
if strings.HasPrefix(secretsProvider, "azurekeyvault://") {
|
||||
parsed, err := url.Parse(secretsProvider)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse secrets provider URL")
|
||||
return errors.Wrap(err, "failed to parse secrets provider URL")
|
||||
}
|
||||
|
||||
if parsed.Query().Get("algorithm") == "" {
|
||||
|
@ -151,10 +165,18 @@ func createStack(
|
|||
}
|
||||
|
||||
if _, secretsErr := newCloudSecretsManager(stackRef.Name(), stackConfigFile, secretsProvider); secretsErr != nil {
|
||||
return nil, secretsErr
|
||||
return secretsErr
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// createStack creates a stack with the given name, and optionally selects it as the current.
|
||||
func createStack(
|
||||
b backend.Backend, stackRef backend.StackReference, opts interface{}, setCurrent bool,
|
||||
secretsProvider string) (backend.Stack, error) {
|
||||
|
||||
stack, err := b.CreateStack(commandContext(), stackRef, opts)
|
||||
if err != nil {
|
||||
// If it's a well-known error, don't wrap it.
|
||||
|
@ -167,6 +189,10 @@ func createStack(
|
|||
return nil, errors.Wrapf(err, "could not create stack")
|
||||
}
|
||||
|
||||
if err := createSecretsManager(b, stackRef, secretsProvider); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if setCurrent {
|
||||
if err = state.SetCurrentStack(stack.Ref().String()); err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -60,6 +60,7 @@ var (
|
|||
goPkgInfo go_gen.GoPackageInfo
|
||||
csharpPkgInfo dotnet.CSharpPackageInfo
|
||||
nodePkgInfo nodejs.NodePackageInfo
|
||||
pythonPkgInfo python.PackageInfo
|
||||
|
||||
// langModuleNameLookup is a map of module name to its language-specific
|
||||
// name.
|
||||
|
@ -347,6 +348,8 @@ func (mod *modContext) getLanguageModuleName(lang string) string {
|
|||
|
||||
switch lang {
|
||||
case "go":
|
||||
// Go module names use lowercase.
|
||||
modName = strings.ToLower(modName)
|
||||
if override, ok := goPkgInfo.ModuleToPackage[modName]; ok {
|
||||
modName = override
|
||||
}
|
||||
|
@ -358,6 +361,10 @@ func (mod *modContext) getLanguageModuleName(lang string) string {
|
|||
if override, ok := nodePkgInfo.ModuleToPackage[modName]; ok {
|
||||
modName = override
|
||||
}
|
||||
case "python":
|
||||
if override, ok := pythonPkgInfo.ModuleNameOverrides[modName]; ok {
|
||||
modName = override
|
||||
}
|
||||
}
|
||||
|
||||
langModuleNameLookup[lookupKey] = modName
|
||||
|
@ -368,11 +375,9 @@ func (mod *modContext) getLanguageModuleName(lang string) string {
|
|||
// The result of this function should be used display purposes only.
|
||||
func (mod *modContext) cleanTypeString(t schema.Type, langTypeString, lang, modName string, isInput bool) string {
|
||||
switch lang {
|
||||
case "go":
|
||||
case "go", "python":
|
||||
parts := strings.Split(langTypeString, ".")
|
||||
return parts[len(parts)-1]
|
||||
case "python":
|
||||
return langTypeString
|
||||
}
|
||||
|
||||
cleanCSharpName := func(pkgName, objModName string) string {
|
||||
|
@ -499,7 +504,11 @@ func cleanOptionalIdentifier(s, lang string) string {
|
|||
case "csharp":
|
||||
return strings.TrimSuffix(s, "?")
|
||||
case "python":
|
||||
return s
|
||||
if strings.HasPrefix(s, "Optional[") && strings.HasSuffix(s, "]") {
|
||||
s = strings.TrimPrefix(s, "Optional[")
|
||||
s = strings.TrimSuffix(s, "]")
|
||||
return s
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
@ -714,6 +723,47 @@ func (mod *modContext) genConstructorCS(r *schema.Resource, argsOptional bool) [
|
|||
}
|
||||
}
|
||||
|
||||
func (mod *modContext) genConstructorPython(r *schema.Resource, argsOptional bool) []formalParam {
|
||||
docLanguageHelper := getLanguageDocHelper("python")
|
||||
isK8sOverlayMod := mod.isKubernetesOverlayModule()
|
||||
isDockerImageResource := mod.pkg.Name == "docker" && resourceName(r) == "Image"
|
||||
|
||||
// Kubernetes overlay resources use a different ordering of formal params in Python.
|
||||
if isK8sOverlayMod {
|
||||
return getKubernetesOverlayPythonFormalParams(mod.mod)
|
||||
} else if isDockerImageResource {
|
||||
return getDockerImagePythonFormalParams()
|
||||
}
|
||||
|
||||
params := make([]formalParam, 0, len(r.InputProperties)+1)
|
||||
// All other resources accept the resource options as a second parameter.
|
||||
params = append(params, formalParam{
|
||||
Name: "opts",
|
||||
DefaultValue: " = None",
|
||||
Type: propertyType{
|
||||
Name: "Optional[ResourceOptions]",
|
||||
Link: "/docs/reference/pkg/python/pulumi/#pulumi.ResourceOptions",
|
||||
},
|
||||
})
|
||||
for _, p := range r.InputProperties {
|
||||
// If the property defines a const value, then skip it.
|
||||
// For example, in k8s, `apiVersion` and `kind` are often hard-coded
|
||||
// in the SDK and are not really user-provided input properties.
|
||||
if p.ConstValue != nil {
|
||||
continue
|
||||
}
|
||||
typ := docLanguageHelper.GetLanguageTypeString(mod.pkg, mod.mod, p.Type, true /*input*/, false /*optional*/)
|
||||
params = append(params, formalParam{
|
||||
Name: python.InitParamName(p.Name),
|
||||
DefaultValue: " = None",
|
||||
Type: propertyType{
|
||||
Name: fmt.Sprintf("Optional[%s]", typ),
|
||||
},
|
||||
})
|
||||
}
|
||||
return params
|
||||
}
|
||||
|
||||
func (mod *modContext) genNestedTypes(member interface{}, resourceType bool) []docNestedType {
|
||||
tokens := nestedTypeUsageInfo{}
|
||||
// Collect all of the types for this "member" as a map of resource names
|
||||
|
@ -835,9 +885,15 @@ func (mod *modContext) getProperties(properties []*schema.Property, lang string,
|
|||
}
|
||||
|
||||
langDocHelper := getLanguageDocHelper(lang)
|
||||
var propLangName string
|
||||
switch lang {
|
||||
case "python":
|
||||
name, err := langDocHelper.GetPropertyName(prop)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
propLangName := name
|
||||
|
||||
// TODO[pulumi/pulumi#5145]: Delete this if check once all providers have UsesIOClasses set to true in their
|
||||
// schema.
|
||||
if lang == "python" && !pythonPkgInfo.UsesIOClasses {
|
||||
pyName := python.PyName(prop.Name)
|
||||
// The default casing for a Python property name is snake_case unless
|
||||
// it is a property of a nested object, in which case, we should check the property
|
||||
|
@ -857,13 +913,6 @@ func (mod *modContext) getProperties(properties []*schema.Property, lang string,
|
|||
propLangName = prop.Name
|
||||
}
|
||||
}
|
||||
default:
|
||||
name, err := langDocHelper.GetPropertyName(prop)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
propLangName = name
|
||||
}
|
||||
|
||||
propID := strings.ToLower(propLangName + propertyLangSeparator + lang)
|
||||
|
@ -926,9 +975,6 @@ func getDockerImagePythonFormalParams() []formalParam {
|
|||
func (mod *modContext) genConstructors(r *schema.Resource, allOptionalInputs bool) (map[string]string, map[string][]formalParam) {
|
||||
renderedParams := make(map[string]string)
|
||||
formalParams := make(map[string][]formalParam)
|
||||
isK8sOverlayMod := mod.isKubernetesOverlayModule()
|
||||
isK8sPackage := isKubernetesPackage(mod.pkg)
|
||||
isDockerImageResource := mod.pkg.Name == "docker" && resourceName(r) == "Image"
|
||||
|
||||
for _, lang := range supportedLanguages {
|
||||
var (
|
||||
|
@ -948,59 +994,19 @@ func (mod *modContext) genConstructors(r *schema.Resource, allOptionalInputs boo
|
|||
params = mod.genConstructorCS(r, allOptionalInputs)
|
||||
paramTemplate = "csharp_formal_param"
|
||||
case "python":
|
||||
params = mod.genConstructorPython(r, allOptionalInputs)
|
||||
paramTemplate = "py_formal_param"
|
||||
// The Pulumi Python SDK does not have types for constructor args.
|
||||
// All of the input properties are spread out in the signature as format params.
|
||||
|
||||
// Kubernetes overlay resources use a different ordering of formal params in Python.
|
||||
if isK8sOverlayMod {
|
||||
params = getKubernetesOverlayPythonFormalParams(mod.mod)
|
||||
break
|
||||
} else if isDockerImageResource {
|
||||
params = getDockerImagePythonFormalParams()
|
||||
break
|
||||
}
|
||||
|
||||
params = make([]formalParam, 0, len(r.InputProperties)+1)
|
||||
// All other resources accept the resource options as a second parameter.
|
||||
params = append(params, formalParam{
|
||||
Name: "opts",
|
||||
DefaultValue: "=None",
|
||||
})
|
||||
for _, p := range r.InputProperties {
|
||||
// If the property defines a const value, then skip it.
|
||||
// For example, in k8s, `apiVersion` and `kind` are often hard-coded
|
||||
// in the SDK and are not really user-provided input properties.
|
||||
if p.ConstValue != nil {
|
||||
continue
|
||||
}
|
||||
params = append(params, formalParam{
|
||||
Name: python.PyName(p.Name),
|
||||
DefaultValue: "=None",
|
||||
})
|
||||
}
|
||||
|
||||
// Kubernetes resources do not accept a props param.
|
||||
if isK8sPackage {
|
||||
break
|
||||
}
|
||||
|
||||
params = append(params, formalParam{
|
||||
Name: "__props__",
|
||||
DefaultValue: "=None",
|
||||
})
|
||||
}
|
||||
|
||||
n := len(params)
|
||||
for i, p := range params {
|
||||
if err := templates.ExecuteTemplate(b, paramTemplate, p); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if i != n-1 {
|
||||
if i != 0 {
|
||||
if err := templates.ExecuteTemplate(b, "param_separator", nil); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
if err := templates.ExecuteTemplate(b, paramTemplate, p); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
renderedParams[lang] = b.String()
|
||||
formalParams[lang] = params
|
||||
|
@ -1181,6 +1187,24 @@ func (mod *modContext) getCSLookupParams(r *schema.Resource, stateParam string)
|
|||
}
|
||||
}
|
||||
|
||||
func (mod *modContext) getPythonLookupParams(r *schema.Resource, stateParam string) []formalParam {
|
||||
// The input properties for a resource needs to be exploded as
|
||||
// individual constructor params.
|
||||
docLanguageHelper := getLanguageDocHelper("python")
|
||||
params := make([]formalParam, 0, len(r.StateInputs.Properties))
|
||||
for _, p := range r.StateInputs.Properties {
|
||||
typ := docLanguageHelper.GetLanguageTypeString(mod.pkg, mod.mod, p.Type, true /*input*/, false /*optional*/)
|
||||
params = append(params, formalParam{
|
||||
Name: python.PyName(p.Name),
|
||||
DefaultValue: " = None",
|
||||
Type: propertyType{
|
||||
Name: fmt.Sprintf("Optional[%s]", typ),
|
||||
},
|
||||
})
|
||||
}
|
||||
return params
|
||||
}
|
||||
|
||||
// genLookupParams generates a map of per-language way of rendering the formal parameters of the lookup function
|
||||
// used to lookup an existing resource.
|
||||
func (mod *modContext) genLookupParams(r *schema.Resource, stateParam string) map[string]string {
|
||||
|
@ -1207,17 +1231,8 @@ func (mod *modContext) genLookupParams(r *schema.Resource, stateParam string) ma
|
|||
params = mod.getCSLookupParams(r, stateParam)
|
||||
paramTemplate = "csharp_formal_param"
|
||||
case "python":
|
||||
params = mod.getPythonLookupParams(r, stateParam)
|
||||
paramTemplate = "py_formal_param"
|
||||
// The Pulumi Python SDK does not yet have types for formal parameters.
|
||||
// The input properties for a resource needs to be exploded as
|
||||
// individual constructor params.
|
||||
params = make([]formalParam, 0, len(r.StateInputs.Properties))
|
||||
for _, p := range r.StateInputs.Properties {
|
||||
params = append(params, formalParam{
|
||||
Name: python.PyName(p.Name),
|
||||
DefaultValue: "=None",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
n := len(params)
|
||||
|
@ -1728,6 +1743,8 @@ func getMod(pkg *schema.Package, token string, modules map[string]*modContext, t
|
|||
// If the parent name is blank, it means this is the package-level.
|
||||
if parentName == "." || parentName == "" {
|
||||
parentName = ":index:"
|
||||
} else {
|
||||
parentName = ":" + parentName + ":"
|
||||
}
|
||||
parent := getMod(pkg, parentName, modules, tool)
|
||||
parent.children = append(parent.children, mod)
|
||||
|
@ -1765,6 +1782,7 @@ func generateModulesFromSchemaPackage(tool string, pkg *schema.Package) map[stri
|
|||
goPkgInfo, _ = pkg.Language["go"].(go_gen.GoPackageInfo)
|
||||
csharpPkgInfo, _ = pkg.Language["csharp"].(dotnet.CSharpPackageInfo)
|
||||
nodePkgInfo, _ = pkg.Language["nodejs"].(nodejs.NodePackageInfo)
|
||||
pythonPkgInfo, _ = pkg.Language["python"].(python.PackageInfo)
|
||||
|
||||
goLangHelper := getLanguageDocHelper("go").(*go_gen.DocLanguageHelper)
|
||||
// Generate the Go package map info now, so we can use that to get the type string
|
||||
|
|
|
@ -87,8 +87,7 @@ func (mod *modContext) getFunctionResourceInfo(f *schema.Function) map[string]pr
|
|||
}
|
||||
|
||||
case "python":
|
||||
// Pulumi's Python language SDK does not have "types" yet, so we will skip it for now.
|
||||
continue
|
||||
resultTypeName = docLangHelper.GetResourceFunctionResultName(mod.mod, f)
|
||||
default:
|
||||
panic(errors.Errorf("cannot generate function resource info for unhandled language %q", lang))
|
||||
}
|
||||
|
@ -212,6 +211,7 @@ func (mod *modContext) genFunctionCS(f *schema.Function, funcName string) []form
|
|||
}
|
||||
|
||||
func (mod *modContext) genFunctionPython(f *schema.Function, resourceName string) []formalParam {
|
||||
docLanguageHelper := getLanguageDocHelper("python")
|
||||
var params []formalParam
|
||||
|
||||
// Some functions don't have any inputs other than the InvokeOptions.
|
||||
|
@ -219,11 +219,14 @@ func (mod *modContext) genFunctionPython(f *schema.Function, resourceName string
|
|||
if f.Inputs != nil {
|
||||
params = make([]formalParam, 0, len(f.Inputs.Properties))
|
||||
for _, prop := range f.Inputs.Properties {
|
||||
fArg := formalParam{
|
||||
typ := docLanguageHelper.GetLanguageTypeString(mod.pkg, mod.mod, prop.Type, true /*input*/, false /*optional*/)
|
||||
params = append(params, formalParam{
|
||||
Name: python.PyName(prop.Name),
|
||||
DefaultValue: "=None",
|
||||
}
|
||||
params = append(params, fArg)
|
||||
DefaultValue: " = None",
|
||||
Type: propertyType{
|
||||
Name: fmt.Sprintf("Optional[%s]", typ),
|
||||
},
|
||||
})
|
||||
}
|
||||
} else {
|
||||
params = make([]formalParam, 0, 1)
|
||||
|
@ -231,7 +234,11 @@ func (mod *modContext) genFunctionPython(f *schema.Function, resourceName string
|
|||
|
||||
params = append(params, formalParam{
|
||||
Name: "opts",
|
||||
DefaultValue: "=None",
|
||||
DefaultValue: " = None",
|
||||
Type: propertyType{
|
||||
Name: "Optional[InvokeOptions]",
|
||||
Link: "/docs/reference/pkg/python/pulumi/#pulumi.InvokeOptions",
|
||||
},
|
||||
})
|
||||
|
||||
return params
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
|
||||
{{ define "csharp_formal_param" }}{{ template "linkify_param" .Type }}<span class="p">{{ .OptionalFlag }} </span><span class="nx">{{ .Name }}{{ .DefaultValue }}{{ end }}
|
||||
|
||||
{{ define "py_formal_param" }}{{ .Name }}{{ .DefaultValue }}{{ end }}
|
||||
{{ define "py_formal_param" }}<span class="nx">{{ .Name }}</span><span class="p">:</span> {{ template "linkify_param" .Type }}{{ .DefaultValue }}{{ end }}
|
||||
|
|
2
pkg/codegen/docs/templates/function.tmpl
vendored
2
pkg/codegen/docs/templates/function.tmpl
vendored
|
@ -24,7 +24,7 @@
|
|||
|
||||
<!-- Python -->
|
||||
{{ print "{{% choosable language python %}}" }}
|
||||
<div class="highlight"><pre class="chroma"><code class="language-python" data-lang="python"><span class="k">function </span> {{ .FunctionName.python }}(</span>{{ htmlSafe .FunctionArgs.python }}<span class="p">)</span></code></pre></div>
|
||||
<div class="highlight"><pre class="chroma"><code class="language-python" data-lang="python"><span class="k">def </span>{{ .FunctionName.python }}(</span>{{ htmlSafe .FunctionArgs.python }}<span class="p">) -></span> {{ .FunctionResult.python.Name }}</code></pre></div>
|
||||
{{ print "{{% /choosable %}}" }}
|
||||
|
||||
<!-- Go -->
|
||||
|
|
5
pkg/codegen/docs/templates/resource.tmpl
vendored
5
pkg/codegen/docs/templates/resource.tmpl
vendored
|
@ -31,7 +31,7 @@
|
|||
{{ htmlSafe "{{% /choosable %}}" }}
|
||||
|
||||
{{ htmlSafe "{{% choosable language python %}}" }}
|
||||
<div class="highlight"><pre class="chroma"><code class="language-python" data-lang="python"><span class="k">def </span>{{ template "linkify_param" .ConstructorResource.python }}<span class="p">(resource_name, </span>{{ htmlSafe .ConstructorParams.python }}<span class="p">)</span></code></pre></div>
|
||||
<div class="highlight"><pre class="chroma"><code class="language-python" data-lang="python"><span class="k">def </span>{{ template "linkify_param" .ConstructorResource.python }}<span class="p">(</span><span class="nx">resource_name</span><span class="p">:</span> <span class="nx">str</span><span class="p">, </span>{{ htmlSafe .ConstructorParams.python }}<span class="p">)</span></code></pre></div>
|
||||
{{ htmlSafe "{{% /choosable %}}" }}
|
||||
|
||||
{{ htmlSafe "{{% choosable language go %}}" }}
|
||||
|
@ -111,7 +111,8 @@ Get an existing {{.Header.Title}} resource's state with the given name, ID, and
|
|||
{{ htmlSafe "{{% /choosable %}}" }}
|
||||
|
||||
{{ htmlSafe "{{% choosable language python %}}" }}
|
||||
<div class="highlight"><pre class="chroma"><code class="language-python" data-lang="python"><span class="k">static </span><span class="nf">get</span><span class="p">(resource_name, id, opts=None, </span>{{ htmlSafe .LookupParams.python }}<span class="p">, __props__=None)</span></code></pre></div>
|
||||
<div class="highlight"><pre class="chroma"><code class="language-python" data-lang="python"><span class=nd>@staticmethod</span>
|
||||
<span class="k">def </span><span class="nf">get</span><span class="p">(</span><span class="nx">resource_name</span><span class="p">:</span> <span class="nx">str</span><span class="p">, </span><span class="nx">id</span><span class="p">:</span> <span class="nx">str</span><span class="p">, </span><span class="nx">opts</span><span class="p">:</span> <span class="nx"><a href="/docs/reference/pkg/python/pulumi/#pulumi.ResourceOptions">Optional[ResourceOptions]</a></span> = None<span class="p">, </span>{{ htmlSafe .LookupParams.python }}<span class="p">) -></span> {{ .ConstructorResource.python.Name }}</code></pre></div>
|
||||
{{ htmlSafe "{{% /choosable %}}" }}
|
||||
|
||||
{{ htmlSafe "{{% choosable language go %}}" }}
|
||||
|
|
2
pkg/codegen/docs/templates/utils.tmpl
vendored
2
pkg/codegen/docs/templates/utils.tmpl
vendored
|
@ -1,5 +1,5 @@
|
|||
<!-- linkify_param is used to wrap constructor/function params in an anchor tag. -->
|
||||
{{ define "linkify_param" }}<span class="nx"><a href="{{ .Link }}">{{ if ne .DisplayName "" }}{{ .DisplayName }}{{ else }}{{ .Name }}{{ end }}</a></span>{{ end }}
|
||||
{{ define "linkify_param" }}<span class="nx">{{ if ne .Link "" }}<a href="{{ .Link }}">{{ end }}{{ if ne .DisplayName "" }}{{ .DisplayName }}{{ else }}{{ .Name }}{{ end }}{{ if ne .Link "" }}</a>{{ end }}</span>{{ end }}
|
||||
|
||||
<!-- linkify_go_param is used to wrap constructor/function params in an anchor tag specifically for go constuctors. We are treating this as a snowflake for now. -->
|
||||
{{ define "linkify_go_param" }}<span class="nx"><a href="{{ .Link }}">New{{ if ne .DisplayName "" }}{{ .DisplayName }}{{ else }}{{ .Name }}{{ end }}</a></span>{{ end }}
|
||||
|
|
|
@ -36,7 +36,17 @@ var _ codegen.DocLanguageHelper = DocLanguageHelper{}
|
|||
|
||||
// GetDocLinkForPulumiType returns the .Net API doc link for a Pulumi type.
|
||||
func (d DocLanguageHelper) GetDocLinkForPulumiType(pkg *schema.Package, typeName string) string {
|
||||
return fmt.Sprintf("/docs/reference/pkg/dotnet/Pulumi/%s.html", typeName)
|
||||
var filename string
|
||||
switch typeName {
|
||||
// We use docfx to generate the .NET language docs. docfx adds a suffix
|
||||
// to generic classes. The suffix depends on the number of type args the class accepts,
|
||||
// which in the case of the Pulumi.Input class is 1.
|
||||
case "Pulumi.Input":
|
||||
filename = "Pulumi.Input-1"
|
||||
default:
|
||||
filename = typeName
|
||||
}
|
||||
return fmt.Sprintf("/docs/reference/pkg/dotnet/Pulumi/%s.html", filename)
|
||||
}
|
||||
|
||||
// GetDocLinkForResourceType returns the .NET API doc URL for a type belonging to a resource provider.
|
||||
|
|
|
@ -36,6 +36,10 @@ type generator struct {
|
|||
program *hcl2.Program
|
||||
// C# namespace map per package.
|
||||
namespaces map[string]map[string]string
|
||||
// C# codegen compatibility mode per package.
|
||||
compatibilities map[string]string
|
||||
// A function to convert tokens to module names per package (utilizes the `moduleFormat` setting internally).
|
||||
tokenToModules map[string]func(x string) string
|
||||
// Type names per invoke function token.
|
||||
functionArgs map[string]string
|
||||
// Whether awaits are needed, and therefore an async Initialize method should be declared.
|
||||
|
@ -44,20 +48,27 @@ type generator struct {
|
|||
diagnostics hcl.Diagnostics
|
||||
}
|
||||
|
||||
const pulumiPackage = "pulumi"
|
||||
|
||||
func GenerateProgram(program *hcl2.Program) (map[string][]byte, hcl.Diagnostics, error) {
|
||||
// Linearize the nodes into an order appropriate for procedural code generation.
|
||||
nodes := hcl2.Linearize(program)
|
||||
|
||||
// Import C#-specific schema info.
|
||||
namespaces := make(map[string]map[string]string)
|
||||
compatibilities := make(map[string]string)
|
||||
tokenToModules := make(map[string]func(x string) string)
|
||||
functionArgs := make(map[string]string)
|
||||
for _, p := range program.Packages() {
|
||||
if err := p.ImportLanguages(map[string]schema.Language{"csharp": Importer}); err != nil {
|
||||
return make(map[string][]byte), nil, err
|
||||
}
|
||||
|
||||
packageNamespaces := p.Language["csharp"].(CSharpPackageInfo).Namespaces
|
||||
csharpInfo := p.Language["csharp"].(CSharpPackageInfo)
|
||||
packageNamespaces := csharpInfo.Namespaces
|
||||
namespaces[p.Name] = packageNamespaces
|
||||
compatibilities[p.Name] = csharpInfo.Compatibility
|
||||
tokenToModules[p.Name] = p.TokenToModule
|
||||
|
||||
for _, f := range p.Functions {
|
||||
if f.Inputs != nil {
|
||||
|
@ -67,9 +78,11 @@ func GenerateProgram(program *hcl2.Program) (map[string][]byte, hcl.Diagnostics,
|
|||
}
|
||||
|
||||
g := &generator{
|
||||
program: program,
|
||||
namespaces: namespaces,
|
||||
functionArgs: functionArgs,
|
||||
program: program,
|
||||
namespaces: namespaces,
|
||||
compatibilities: compatibilities,
|
||||
tokenToModules: tokenToModules,
|
||||
functionArgs: functionArgs,
|
||||
}
|
||||
g.Formatter = format.NewFormatter(g)
|
||||
|
||||
|
@ -133,7 +146,7 @@ func (g *generator) genPreamble(w io.Writer, program *hcl2.Program) {
|
|||
for _, n := range program.Nodes {
|
||||
if r, isResource := n.(*hcl2.Resource); isResource {
|
||||
pkg, _, _, _ := r.DecomposeToken()
|
||||
if pkg != "pulumi" {
|
||||
if pkg != pulumiPackage {
|
||||
namespace := namespaceName(g.namespaces[pkg], pkg)
|
||||
pulumiUsings.Add(fmt.Sprintf("%s = Pulumi.%[1]s", namespace))
|
||||
}
|
||||
|
@ -260,14 +273,13 @@ func (g *generator) resourceTypeName(r *hcl2.Resource) string {
|
|||
// Compute the resource type from the Pulumi type token.
|
||||
pkg, module, member, diags := r.DecomposeToken()
|
||||
contract.Assert(len(diags) == 0)
|
||||
if pkg == "pulumi" && module == "providers" {
|
||||
if pkg == pulumiPackage && module == "providers" {
|
||||
pkg, module, member = member, "", "Provider"
|
||||
}
|
||||
|
||||
namespaces := g.namespaces[pkg]
|
||||
namespaceKey := strings.Replace(module, "/", ".", -1)
|
||||
rootNamespace := namespaceName(namespaces, pkg)
|
||||
namespace := namespaceName(namespaces, namespaceKey)
|
||||
namespace := namespaceName(namespaces, module)
|
||||
|
||||
if namespace != "" {
|
||||
namespace = "." + namespace
|
||||
|
@ -277,6 +289,29 @@ func (g *generator) resourceTypeName(r *hcl2.Resource) string {
|
|||
return qualifiedMemberName
|
||||
}
|
||||
|
||||
// resourceArgsTypeName computes the C# arguments class name for the given resource.
|
||||
func (g *generator) resourceArgsTypeName(r *hcl2.Resource) string {
|
||||
// Compute the resource type from the Pulumi type token.
|
||||
pkg, module, member, diags := r.DecomposeToken()
|
||||
contract.Assert(len(diags) == 0)
|
||||
if pkg == pulumiPackage && module == "providers" {
|
||||
pkg, module, member = member, "", "Provider"
|
||||
}
|
||||
|
||||
namespaces := g.namespaces[pkg]
|
||||
rootNamespace := namespaceName(namespaces, pkg)
|
||||
namespace := namespaceName(namespaces, module)
|
||||
if g.compatibilities[pkg] == "kubernetes20" {
|
||||
namespace = fmt.Sprintf("Types.Inputs.%s", namespace)
|
||||
}
|
||||
|
||||
if namespace != "" {
|
||||
namespace = "." + namespace
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s%s.%sArgs", rootNamespace, namespace, Title(member))
|
||||
}
|
||||
|
||||
// functionName computes the C# namespace and class name for the given function token.
|
||||
func (g *generator) functionName(tokenArg model.Expression) (string, string) {
|
||||
token := tokenArg.(*model.TemplateExpression).Parts[0].(*model.LiteralValueExpression).Value.AsString()
|
||||
|
@ -286,9 +321,8 @@ func (g *generator) functionName(tokenArg model.Expression) (string, string) {
|
|||
pkg, module, member, diags := hcl2.DecomposeToken(token, tokenRange)
|
||||
contract.Assert(len(diags) == 0)
|
||||
namespaces := g.namespaces[pkg]
|
||||
namespaceKey := strings.Replace(module, "/", ".", -1)
|
||||
rootNamespace := namespaceName(namespaces, pkg)
|
||||
namespace := namespaceName(namespaces, namespaceKey)
|
||||
namespace := namespaceName(namespaces, module)
|
||||
|
||||
if namespace != "" {
|
||||
namespace = "." + namespace
|
||||
|
@ -317,19 +351,21 @@ func (g *generator) argumentTypeName(expr model.Expression, destType model.Type)
|
|||
qualifier = ""
|
||||
}
|
||||
|
||||
pkg, module, member, diags := hcl2.DecomposeToken(token, tokenRange)
|
||||
pkg, _, member, diags := hcl2.DecomposeToken(token, tokenRange)
|
||||
contract.Assert(len(diags) == 0)
|
||||
module := g.tokenToModules[pkg](token)
|
||||
namespaces := g.namespaces[pkg]
|
||||
namespaceKey := strings.Split(module, "/")[0]
|
||||
rootNamespace := namespaceName(namespaces, pkg)
|
||||
namespace := namespaceName(namespaces, namespaceKey)
|
||||
namespace := namespaceName(namespaces, module)
|
||||
if strings.ToLower(namespace) == "index" {
|
||||
namespace = ""
|
||||
}
|
||||
if namespace != "" {
|
||||
namespace = "." + namespace
|
||||
}
|
||||
if qualifier != "" {
|
||||
if g.compatibilities[pkg] == "kubernetes20" {
|
||||
namespace = ".Types.Inputs" + namespace
|
||||
} else if qualifier != "" {
|
||||
namespace = namespace + "." + qualifier
|
||||
}
|
||||
member = member + "Args"
|
||||
|
@ -390,6 +426,7 @@ func (g *generator) genResourceOptions(opts *hcl2.ResourceOptions) string {
|
|||
// genResource handles the generation of instantiations of non-builtin resources.
|
||||
func (g *generator) genResource(w io.Writer, r *hcl2.Resource) {
|
||||
qualifiedMemberName := g.resourceTypeName(r)
|
||||
argsName := g.resourceArgsTypeName(r)
|
||||
|
||||
// Add conversions to input properties
|
||||
for _, input := range r.Inputs {
|
||||
|
@ -408,7 +445,7 @@ func (g *generator) genResource(w io.Writer, r *hcl2.Resource) {
|
|||
g.genTrivia(w, r.Definition.Tokens.GetOpenBrace())
|
||||
|
||||
instantiate := func(resName string) {
|
||||
g.Fgenf(w, "new %s(%s, new %[1]sArgs\n", qualifiedMemberName, resName)
|
||||
g.Fgenf(w, "new %s(%s, new %s\n", qualifiedMemberName, resName, argsName)
|
||||
g.Fgenf(w, "%s{\n", g.Indent)
|
||||
g.Indented(func() {
|
||||
for _, attr := range r.Inputs {
|
||||
|
|
|
@ -17,7 +17,6 @@ package dotnet
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/pulumi/pulumi/pkg/v2/codegen/schema"
|
||||
"io"
|
||||
"math/big"
|
||||
"strings"
|
||||
|
@ -26,6 +25,7 @@ import (
|
|||
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||
"github.com/pulumi/pulumi/pkg/v2/codegen/hcl2"
|
||||
"github.com/pulumi/pulumi/pkg/v2/codegen/hcl2/model"
|
||||
"github.com/pulumi/pulumi/pkg/v2/codegen/schema"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/util/contract"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
@ -402,6 +402,8 @@ func (g *generator) GenLiteralValueExpression(w io.Writer, expr *model.LiteralVa
|
|||
switch expr.Type() {
|
||||
case model.BoolType:
|
||||
g.Fgenf(w, "%v", expr.Value.True())
|
||||
case model.NoneType:
|
||||
g.Fgen(w, "null")
|
||||
case model.NumberType:
|
||||
bf := expr.Value.AsBigFloat()
|
||||
if i, acc := bf.Int64(); acc == big.Exact {
|
||||
|
|
|
@ -1221,8 +1221,11 @@ func LanguageResources(tool string, pkg *schema.Package) (map[string]LanguageRes
|
|||
return nil, err
|
||||
}
|
||||
|
||||
goInfo, _ := pkg.Language["go"].(GoPackageInfo)
|
||||
packages := generatePackageContextMap(tool, pkg, goInfo)
|
||||
var goPkgInfo GoPackageInfo
|
||||
if goInfo, ok := pkg.Language["go"].(GoPackageInfo); ok {
|
||||
goPkgInfo = goInfo
|
||||
}
|
||||
packages := generatePackageContextMap(tool, pkg, goPkgInfo)
|
||||
|
||||
// emit each package
|
||||
var pkgMods []string
|
||||
|
@ -1238,10 +1241,10 @@ func LanguageResources(tool string, pkg *schema.Package) (map[string]LanguageRes
|
|||
pkg := packages[mod]
|
||||
|
||||
for _, r := range pkg.resources {
|
||||
packagePath := path.Join(goInfo.ImportBasePath, pkg.mod)
|
||||
packagePath := path.Join(goPkgInfo.ImportBasePath, pkg.mod)
|
||||
resources[r.Token] = LanguageResource{
|
||||
Resource: r,
|
||||
Alias: goInfo.PackageImportAliases[packagePath],
|
||||
Alias: goPkgInfo.PackageImportAliases[packagePath],
|
||||
Name: tokenToName(r.Token),
|
||||
Package: packagePath,
|
||||
}
|
||||
|
@ -1256,8 +1259,11 @@ func GeneratePackage(tool string, pkg *schema.Package) (map[string][]byte, error
|
|||
return nil, err
|
||||
}
|
||||
|
||||
goInfo, _ := pkg.Language["go"].(GoPackageInfo)
|
||||
packages := generatePackageContextMap(tool, pkg, goInfo)
|
||||
var goPkgInfo GoPackageInfo
|
||||
if goInfo, ok := pkg.Language["go"].(GoPackageInfo); ok {
|
||||
goPkgInfo = goInfo
|
||||
}
|
||||
packages := generatePackageContextMap(tool, pkg, goPkgInfo)
|
||||
|
||||
// emit each package
|
||||
var pkgMods []string
|
||||
|
|
55
pkg/codegen/go/gen_crd2pulumi.go
Normal file
55
pkg/codegen/go/gen_crd2pulumi.go
Normal file
|
@ -0,0 +1,55 @@
|
|||
package gen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/pulumi/pulumi/pkg/v2/codegen/schema"
|
||||
)
|
||||
|
||||
// CRDTypes returns a map from each module name to a buffer containing the
|
||||
// code for its generated types.
|
||||
func CRDTypes(tool string, pkg *schema.Package) (map[string]*bytes.Buffer, error) {
|
||||
if err := pkg.ImportLanguages(map[string]schema.Language{"go": Importer}); err != nil {
|
||||
return map[string]*bytes.Buffer{}, err
|
||||
}
|
||||
|
||||
var goPkgInfo GoPackageInfo
|
||||
if goInfo, ok := pkg.Language["go"].(GoPackageInfo); ok {
|
||||
goPkgInfo = goInfo
|
||||
}
|
||||
packages := generatePackageContextMap(tool, pkg, goPkgInfo)
|
||||
|
||||
var pkgMods []string
|
||||
for mod := range packages {
|
||||
pkgMods = append(pkgMods, mod)
|
||||
}
|
||||
|
||||
buffers := map[string]*bytes.Buffer{}
|
||||
|
||||
for _, mod := range pkgMods {
|
||||
pkg := packages[mod]
|
||||
buffer := &bytes.Buffer{}
|
||||
|
||||
for _, r := range pkg.resources {
|
||||
imports := stringSet{}
|
||||
pkg.getImports(r, imports)
|
||||
pkg.genHeader(buffer, []string{"context", "reflect"}, imports)
|
||||
|
||||
if err := pkg.genResource(buffer, r); err != nil {
|
||||
return nil, errors.Wrapf(err, "generating resource %s", mod)
|
||||
}
|
||||
}
|
||||
|
||||
if len(pkg.types) > 0 {
|
||||
for _, t := range pkg.types {
|
||||
pkg.genType(buffer, t)
|
||||
}
|
||||
pkg.genTypeRegistrations(buffer, pkg.types)
|
||||
}
|
||||
|
||||
buffers[mod] = buffer
|
||||
}
|
||||
|
||||
return buffers, nil
|
||||
}
|
|
@ -22,6 +22,7 @@ type generator struct {
|
|||
// The formatter to use when generating code.
|
||||
*format.Formatter
|
||||
program *hcl2.Program
|
||||
packages map[string]*schema.Package
|
||||
contexts map[string]map[string]*pkgContext
|
||||
diagnostics hcl.Diagnostics
|
||||
jsonTempSpiller *jsonSpiller
|
||||
|
@ -38,14 +39,14 @@ func GenerateProgram(program *hcl2.Program) (map[string][]byte, hcl.Diagnostics,
|
|||
// Linearize the nodes into an order appropriate for procedural code generation.
|
||||
nodes := hcl2.Linearize(program)
|
||||
|
||||
contexts := make(map[string]map[string]*pkgContext)
|
||||
|
||||
packages, contexts := map[string]*schema.Package{}, map[string]map[string]*pkgContext{}
|
||||
for _, pkg := range program.Packages() {
|
||||
contexts[pkg.Name] = getPackages("tool", pkg)
|
||||
packages[pkg.Name], contexts[pkg.Name] = pkg, getPackages("tool", pkg)
|
||||
}
|
||||
|
||||
g := &generator{
|
||||
program: program,
|
||||
packages: packages,
|
||||
contexts: contexts,
|
||||
jsonTempSpiller: &jsonSpiller{},
|
||||
ternaryTempSpiller: &tempSpiller{},
|
||||
|
@ -58,18 +59,31 @@ func GenerateProgram(program *hcl2.Program) (map[string][]byte, hcl.Diagnostics,
|
|||
|
||||
g.Formatter = format.NewFormatter(g)
|
||||
|
||||
var index bytes.Buffer
|
||||
g.genPreamble(&index, program)
|
||||
// we must collect imports once before lowering, and once after.
|
||||
// this allows us to avoid complexity of traversing apply expressions for things like JSON
|
||||
// but still have access to types provided by __convert intrinsics after lowering.
|
||||
pulumiImports := codegen.NewStringSet()
|
||||
stdImports := codegen.NewStringSet()
|
||||
g.collectImports(program, stdImports, pulumiImports)
|
||||
|
||||
var progPostamble bytes.Buffer
|
||||
for _, n := range nodes {
|
||||
g.collectScopeRoots(n)
|
||||
}
|
||||
|
||||
for _, n := range nodes {
|
||||
g.genNode(&index, n)
|
||||
g.genNode(&progPostamble, n)
|
||||
}
|
||||
|
||||
g.genPostamble(&index, nodes)
|
||||
g.genPostamble(&progPostamble, nodes)
|
||||
|
||||
// We must generate the program first and the preamble second and finally cat the two together.
|
||||
// This is because nested object/tuple cons expressions can require imports that aren't
|
||||
// present in resource declarations or invokes alone. Expressions are lowered when the program is generated
|
||||
// and this must happen first so we can access types via __convert intrinsics.
|
||||
var index bytes.Buffer
|
||||
g.genPreamble(&index, program, stdImports, pulumiImports)
|
||||
index.Write(progPostamble.Bytes())
|
||||
|
||||
// Run Go formatter on the code before saving to disk
|
||||
formattedSource, err := gofmt.Source(index.Bytes())
|
||||
|
@ -88,8 +102,11 @@ func getPackages(tool string, pkg *schema.Package) map[string]*pkgContext {
|
|||
return nil
|
||||
}
|
||||
|
||||
goInfo, _ := pkg.Language["go"].(GoPackageInfo)
|
||||
return generatePackageContextMap(tool, pkg, goInfo)
|
||||
var goPkgInfo GoPackageInfo
|
||||
if goInfo, ok := pkg.Language["go"].(GoPackageInfo); ok {
|
||||
goPkgInfo = goInfo
|
||||
}
|
||||
return generatePackageContextMap(tool, pkg, goPkgInfo)
|
||||
}
|
||||
|
||||
func (g *generator) collectScopeRoots(n hcl2.Node) {
|
||||
|
@ -103,11 +120,11 @@ func (g *generator) collectScopeRoots(n hcl2.Node) {
|
|||
}
|
||||
|
||||
// genPreamble generates package decl, imports, and opens the main func
|
||||
func (g *generator) genPreamble(w io.Writer, program *hcl2.Program) {
|
||||
func (g *generator) genPreamble(w io.Writer, program *hcl2.Program, stdImports, pulumiImports codegen.StringSet) {
|
||||
g.Fprint(w, "package main\n\n")
|
||||
g.Fprintf(w, "import (\n")
|
||||
|
||||
stdImports, pulumiImports := g.collectImports(w, program)
|
||||
g.collectImports(program, stdImports, pulumiImports)
|
||||
for _, imp := range stdImports.SortedValues() {
|
||||
g.Fprintf(w, "\"%s\"\n", imp)
|
||||
}
|
||||
|
@ -116,7 +133,7 @@ func (g *generator) genPreamble(w io.Writer, program *hcl2.Program) {
|
|||
g.Fprintf(w, "\"github.com/pulumi/pulumi/sdk/v2/go/pulumi\"\n")
|
||||
|
||||
for _, imp := range pulumiImports.SortedValues() {
|
||||
g.Fprintf(w, "\"%s\"\n", imp)
|
||||
g.Fprintf(w, "%s\n", imp)
|
||||
}
|
||||
|
||||
g.Fprintf(w, ")\n")
|
||||
|
@ -125,10 +142,11 @@ func (g *generator) genPreamble(w io.Writer, program *hcl2.Program) {
|
|||
}
|
||||
|
||||
// collect Imports returns two sets of packages imported by the program, std lib packages and pulumi packages
|
||||
func (g *generator) collectImports(w io.Writer, program *hcl2.Program) (codegen.StringSet, codegen.StringSet) {
|
||||
func (g *generator) collectImports(
|
||||
program *hcl2.Program,
|
||||
stdImports,
|
||||
pulumiImports codegen.StringSet) (codegen.StringSet, codegen.StringSet) {
|
||||
// Accumulate import statements for the various providers
|
||||
pulumiImports := codegen.NewStringSet()
|
||||
stdImports := codegen.NewStringSet()
|
||||
for _, n := range program.Nodes {
|
||||
if r, isResource := n.(*hcl2.Resource); isResource {
|
||||
pkg, mod, name, _ := r.DecomposeToken()
|
||||
|
@ -136,27 +154,12 @@ func (g *generator) collectImports(w io.Writer, program *hcl2.Program) (codegen.
|
|||
pkg = name
|
||||
}
|
||||
|
||||
version := -1
|
||||
for _, p := range program.Packages() {
|
||||
if p.Name == pkg {
|
||||
version = int(p.Version.Major)
|
||||
break
|
||||
}
|
||||
vPath, err := g.getVersionPath(program, pkg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if version == -1 {
|
||||
panic(errors.Errorf("could not find package information for resource with type token:\n\n%s", r.Token))
|
||||
}
|
||||
|
||||
var vPath string
|
||||
if version > 1 {
|
||||
vPath = fmt.Sprintf("/v%d", version)
|
||||
}
|
||||
if mod == "" {
|
||||
pulumiImports.Add(fmt.Sprintf("github.com/pulumi/pulumi-%s/sdk%s/go/%s", pkg, vPath, pkg))
|
||||
} else {
|
||||
pulumiImports.Add(fmt.Sprintf("github.com/pulumi/pulumi-%s/sdk%s/go/%s/%s", pkg, vPath, pkg, mod))
|
||||
}
|
||||
pulumiImports.Add(g.getPulumiImport(pkg, vPath, mod))
|
||||
}
|
||||
|
||||
diags := n.VisitExpressions(nil, func(n model.Expression) (model.Expression, hcl.Diagnostics) {
|
||||
|
@ -169,28 +172,34 @@ func (g *generator) collectImports(w io.Writer, program *hcl2.Program) (codegen.
|
|||
|
||||
contract.Assert(len(diagnostics) == 0)
|
||||
|
||||
version := -1
|
||||
for _, p := range program.Packages() {
|
||||
if p.Name == pkg {
|
||||
version = int(p.Version.Major)
|
||||
break
|
||||
vPath, err := g.getVersionPath(program, pkg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pulumiImports.Add(g.getPulumiImport(pkg, vPath, mod))
|
||||
} else if call.Name == hcl2.IntrinsicConvert {
|
||||
if schemaType, ok := hcl2.GetSchemaForType(call.Type()); ok {
|
||||
switch schemaType := schemaType.(type) {
|
||||
case *schema.ObjectType:
|
||||
token := schemaType.Token
|
||||
var tokenRange hcl.Range
|
||||
pkg, mod, _, _ := hcl2.DecomposeToken(token, tokenRange)
|
||||
vPath, err := g.getVersionPath(program, pkg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pulumiImports.Add(g.getPulumiImport(pkg, vPath, mod))
|
||||
case *schema.ArrayType:
|
||||
token := schemaType.ElementType.(*schema.ObjectType).Token
|
||||
var tokenRange hcl.Range
|
||||
pkg, mod, _, _ := hcl2.DecomposeToken(token, tokenRange)
|
||||
vPath, err := g.getVersionPath(program, pkg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pulumiImports.Add(g.getPulumiImport(pkg, vPath, mod))
|
||||
}
|
||||
}
|
||||
|
||||
if version == -1 {
|
||||
panic(errors.Errorf("could not find package information for resource with type token:\n\n%s", token))
|
||||
}
|
||||
|
||||
var vPath string
|
||||
if version > 1 {
|
||||
vPath = fmt.Sprintf("/v%d", version)
|
||||
}
|
||||
|
||||
// namespaceless invokes "aws:index:..."
|
||||
if mod == "" {
|
||||
pulumiImports.Add(fmt.Sprintf("github.com/pulumi/pulumi-%s/sdk%s/go/%s", pkg, vPath, pkg))
|
||||
} else {
|
||||
pulumiImports.Add(fmt.Sprintf("github.com/pulumi/pulumi-%s/sdk%s/go/%s/%s", pkg, vPath, pkg, mod))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -217,6 +226,73 @@ func (g *generator) collectImports(w io.Writer, program *hcl2.Program) (codegen.
|
|||
return stdImports, pulumiImports
|
||||
}
|
||||
|
||||
func (g *generator) getVersionPath(program *hcl2.Program, pkg string) (string, error) {
|
||||
version := -1
|
||||
for _, p := range program.Packages() {
|
||||
if p.Name == pkg {
|
||||
version = int(p.Version.Major)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if version == -1 {
|
||||
return "", errors.Errorf("could not find package version information for pkg: %s", pkg)
|
||||
}
|
||||
|
||||
var vPath string
|
||||
if version > 1 {
|
||||
vPath = fmt.Sprintf("/v%d", version)
|
||||
}
|
||||
|
||||
return vPath, nil
|
||||
}
|
||||
|
||||
func (g *generator) getPkgContext(pkg, mod string) (*pkgContext, bool) {
|
||||
p, ok := g.contexts[pkg]
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
m, ok := p[mod]
|
||||
return m, ok
|
||||
}
|
||||
|
||||
func (g *generator) getGoPackageInfo(pkg string) (GoPackageInfo, bool) {
|
||||
p, ok := g.packages[pkg]
|
||||
if !ok {
|
||||
return GoPackageInfo{}, false
|
||||
}
|
||||
info, ok := p.Language["go"].(GoPackageInfo)
|
||||
return info, ok
|
||||
}
|
||||
|
||||
func (g *generator) getPulumiImport(pkg, vPath, mod string) string {
|
||||
info, _ := g.getGoPackageInfo(pkg)
|
||||
if m, ok := info.ModuleToPackage[mod]; ok {
|
||||
mod = m
|
||||
}
|
||||
|
||||
imp := fmt.Sprintf("github.com/pulumi/pulumi-%s/sdk%s/go/%s/%s", pkg, vPath, pkg, mod)
|
||||
// namespaceless invokes "aws:index:..."
|
||||
if mod == "" {
|
||||
imp = fmt.Sprintf("github.com/pulumi/pulumi-%s/sdk%s/go/%s", pkg, vPath, pkg)
|
||||
}
|
||||
|
||||
if alias, ok := info.PackageImportAliases[imp]; ok {
|
||||
return fmt.Sprintf("%s %q", alias, imp)
|
||||
}
|
||||
|
||||
modSplit := strings.Split(mod, "/")
|
||||
// account for mods like "eks/ClusterVpcConfig" index...
|
||||
if len(modSplit) > 1 {
|
||||
if modSplit[0] == "" || modSplit[0] == "index" {
|
||||
imp = fmt.Sprintf("github.com/pulumi/pulumi-%s/sdk%s/go/%s", pkg, vPath, pkg)
|
||||
} else {
|
||||
imp = fmt.Sprintf("github.com/pulumi/pulumi-%s/sdk%s/go/%s/%s", pkg, vPath, pkg, strings.Split(mod, "/")[0])
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("%q", imp)
|
||||
}
|
||||
|
||||
// genPostamble closes the method
|
||||
func (g *generator) genPostamble(w io.Writer, nodes []hcl2.Node) {
|
||||
|
||||
|
@ -326,20 +402,22 @@ func (g *generator) genResource(w io.Writer, r *hcl2.Resource) {
|
|||
g.genTemps(w, temps)
|
||||
}
|
||||
|
||||
modOrAlias := g.getModOrAlias(pkg, mod)
|
||||
|
||||
instantiate := func(varName, resourceName string, w io.Writer) {
|
||||
if g.scopeTraversalRoots.Has(varName) || strings.HasPrefix(varName, "__") {
|
||||
g.Fgenf(w, "%s, err := %s.New%s(ctx, %s, ", varName, mod, typ, resourceName)
|
||||
g.Fgenf(w, "%s, err := %s.New%s(ctx, %s, ", varName, modOrAlias, typ, resourceName)
|
||||
} else {
|
||||
assignment := ":="
|
||||
if g.isErrAssigned {
|
||||
assignment = "="
|
||||
}
|
||||
g.Fgenf(w, "_, err %s %s.New%s(ctx, %s, ", assignment, mod, typ, resourceName)
|
||||
g.Fgenf(w, "_, err %s %s.New%s(ctx, %s, ", assignment, modOrAlias, typ, resourceName)
|
||||
}
|
||||
g.isErrAssigned = true
|
||||
|
||||
if len(r.Inputs) > 0 {
|
||||
g.Fgenf(w, "&%s.%sArgs{\n", mod, typ)
|
||||
g.Fgenf(w, "&%s.%sArgs{\n", modOrAlias, typ)
|
||||
for _, attr := range r.Inputs {
|
||||
g.Fgenf(w, "%s: ", strings.Title(attr.Name))
|
||||
g.Fgenf(w, "%.v,\n", attr.Value)
|
||||
|
@ -361,7 +439,7 @@ func (g *generator) genResource(w io.Writer, r *hcl2.Resource) {
|
|||
rangeExpr, temps := g.lowerExpression(r.Options.Range, rangeType, false)
|
||||
g.genTemps(w, temps)
|
||||
|
||||
g.Fgenf(w, "var %s []*%s.%s\n", resName, mod, typ)
|
||||
g.Fgenf(w, "var %s []*%s.%s\n", resName, modOrAlias, typ)
|
||||
|
||||
// ahead of range statement declaration generate the resource instantiation
|
||||
// to detect and removed unused k,v variables
|
||||
|
@ -529,3 +607,21 @@ func (g *generator) useLookupInvokeForm(token string) bool {
|
|||
|
||||
return false
|
||||
}
|
||||
|
||||
// getModOrAlias attempts to reconstruct the import statement and check if the imported package
|
||||
// is aliased, returning that alias if available.
|
||||
func (g *generator) getModOrAlias(pkg, mod string) string {
|
||||
info, ok := g.getGoPackageInfo(pkg)
|
||||
if !ok {
|
||||
return mod
|
||||
}
|
||||
if m, ok := info.ModuleToPackage[mod]; ok {
|
||||
mod = m
|
||||
}
|
||||
|
||||
imp := fmt.Sprintf("%s/%s", info.ImportBasePath, mod)
|
||||
if alias, ok := info.PackageImportAliases[imp]; ok {
|
||||
return alias
|
||||
}
|
||||
return mod
|
||||
}
|
||||
|
|
|
@ -258,6 +258,11 @@ func (g *generator) GenLiteralValueExpression(w io.Writer, expr *model.LiteralVa
|
|||
}
|
||||
|
||||
func (g *generator) genLiteralValueExpression(w io.Writer, expr *model.LiteralValueExpression, destType model.Type) {
|
||||
if destType == model.NoneType {
|
||||
g.Fgen(w, "nil")
|
||||
return
|
||||
}
|
||||
|
||||
argTypeName := g.argumentTypeName(expr, destType, false)
|
||||
isPulumiType := strings.HasPrefix(argTypeName, "pulumi.")
|
||||
|
||||
|
@ -302,10 +307,15 @@ func (g *generator) genLiteralValueExpression(w io.Writer, expr *model.LiteralVa
|
|||
}
|
||||
// handles the __convert intrinsic assuming that the union type will have an opaque type containing the dest type
|
||||
case *model.UnionType:
|
||||
var didGenerate bool
|
||||
for _, t := range destType.ElementTypes {
|
||||
if didGenerate {
|
||||
break
|
||||
}
|
||||
switch t := t.(type) {
|
||||
case *model.OpaqueType:
|
||||
g.genLiteralValueExpression(w, expr, t)
|
||||
didGenerate = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -572,7 +582,8 @@ func (g *generator) argumentTypeName(expr model.Expression, destType model.Type,
|
|||
if module == "" || strings.HasPrefix(module, "/") || strings.HasPrefix(module, "index/") {
|
||||
module = pkg
|
||||
}
|
||||
importPrefix := strings.Split(module, "/")[0]
|
||||
importPrefix := g.getModOrAlias(pkg, module)
|
||||
importPrefix = strings.Split(importPrefix, "/")[0]
|
||||
contract.Assert(len(diags) == 0)
|
||||
fmtString := "[]%s.%s"
|
||||
if isInput {
|
||||
|
@ -593,7 +604,8 @@ func (g *generator) argumentTypeName(expr model.Expression, destType model.Type,
|
|||
if module == "" || strings.HasPrefix(module, "/") || strings.HasPrefix(module, "index/") {
|
||||
module = pkg
|
||||
}
|
||||
importPrefix := strings.Split(module, "/")[0]
|
||||
importPrefix := g.getModOrAlias(pkg, module)
|
||||
importPrefix = strings.Split(importPrefix, "/")[0]
|
||||
contract.Assert(len(diags) == 0)
|
||||
member = Title(member)
|
||||
if strings.HasPrefix(member, "Get") {
|
||||
|
|
|
@ -68,13 +68,14 @@ func TestGenProgram(t *testing.T) {
|
|||
|
||||
func TestCollectImports(t *testing.T) {
|
||||
g := newTestGenerator(t, "aws-s3-logging.pp")
|
||||
var index bytes.Buffer
|
||||
stdImports, pulumiImports := g.collectImports(&index, g.program)
|
||||
pulumiImports := codegen.NewStringSet()
|
||||
stdImports := codegen.NewStringSet()
|
||||
g.collectImports(g.program, stdImports, pulumiImports)
|
||||
stdVals := stdImports.SortedValues()
|
||||
pulumiVals := pulumiImports.SortedValues()
|
||||
assert.Equal(t, 0, len(stdVals))
|
||||
assert.Equal(t, 1, len(pulumiVals))
|
||||
assert.Equal(t, "github.com/pulumi/pulumi-aws/sdk/v2/go/aws/s3", pulumiVals[0])
|
||||
assert.Equal(t, "\"github.com/pulumi/pulumi-aws/sdk/v2/go/aws/s3\"", pulumiVals[0])
|
||||
}
|
||||
|
||||
func newTestGenerator(t *testing.T, testFile string) *generator {
|
||||
|
|
|
@ -146,7 +146,7 @@ func BindProgram(files []*syntax.File, opts ...BindOption) (*Program, hcl.Diagno
|
|||
}, diagnostics, nil
|
||||
}
|
||||
|
||||
// declareNodes declares all of the top-level nodes in the given file. This invludes config, resources, outputs, and
|
||||
// declareNodes declares all of the top-level nodes in the given file. This includes config, resources, outputs, and
|
||||
// locals.
|
||||
func (b *binder) declareNodes(file *syntax.File) (hcl.Diagnostics, error) {
|
||||
var diagnostics hcl.Diagnostics
|
||||
|
|
|
@ -76,6 +76,7 @@ func (b *binder) bindResourceTypes(node *Resource) hcl.Diagnostics {
|
|||
if !ok {
|
||||
return hcl.Diagnostics{unknownResourceType(token, tokenRange)}
|
||||
}
|
||||
node.Schema = res
|
||||
inputProperties, properties = res.InputProperties, res.Properties
|
||||
} else {
|
||||
inputProperties, properties = pkgSchema.schema.Config, pkgSchema.schema.Config
|
||||
|
|
|
@ -211,7 +211,7 @@ var schemaArrayTypes = make(map[schema.Type]*schema.ArrayType)
|
|||
|
||||
// GetSchemaForType extracts the schema.Type associated with a model.Type, if any.
|
||||
//
|
||||
// The result may be a *schema.UnionType if multiple schema types are associaged with the input type.
|
||||
// The result may be a *schema.UnionType if multiple schema types are associated with the input type.
|
||||
func GetSchemaForType(t model.Type) (schema.Type, bool) {
|
||||
switch t := t.(type) {
|
||||
case *model.ListType:
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||
"github.com/pulumi/pulumi/pkg/v2/codegen/hcl2/model"
|
||||
"github.com/pulumi/pulumi/pkg/v2/codegen/hcl2/syntax"
|
||||
"github.com/pulumi/pulumi/pkg/v2/codegen/schema"
|
||||
)
|
||||
|
||||
// ResourceOptions represents a resource instantiation's options.
|
||||
|
@ -52,6 +53,9 @@ type Resource struct {
|
|||
// Token is the type token for this resource.
|
||||
Token string
|
||||
|
||||
// Schema is the schema definition for this resource, if any.
|
||||
Schema *schema.Resource
|
||||
|
||||
// The type of the resource's inputs. This will always be either Any or an object type.
|
||||
InputType model.Type
|
||||
// The type of the resource's outputs. This will always be either Any or an object type.
|
||||
|
|
|
@ -13,5 +13,8 @@ func NewHost(schemaDirectoryPath string) plugin.Host {
|
|||
}),
|
||||
deploytest.NewProviderLoader("random", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
||||
return Random(schemaDirectoryPath)
|
||||
}),
|
||||
deploytest.NewProviderLoader("kubernetes", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
||||
return Kubernetes(schemaDirectoryPath)
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -35,3 +35,15 @@ func Random(schemaDirectoryPath string) (plugin.Provider, error) {
|
|||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func Kubernetes(schemaDirectoryPath string) (plugin.Provider, error) {
|
||||
schema, err := GetSchema(schemaDirectoryPath, "kubernetes")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &deploytest.Provider{
|
||||
GetSchemaF: func(version int) ([]byte, error) {
|
||||
return schema, nil
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
|
58
pkg/codegen/internal/test/testdata/aws-eks.pp.py
vendored
58
pkg/codegen/internal/test/testdata/aws-eks.pp.py
vendored
|
@ -18,10 +18,10 @@ eks_igw = aws.ec2.InternetGateway("eksIgw",
|
|||
})
|
||||
eks_route_table = aws.ec2.RouteTable("eksRouteTable",
|
||||
vpc_id=eks_vpc.id,
|
||||
routes=[{
|
||||
"cidr_block": "0.0.0.0/0",
|
||||
"gateway_id": eks_igw.id,
|
||||
}],
|
||||
routes=[aws.ec2.RouteTableRouteArgs(
|
||||
cidr_block="0.0.0.0/0",
|
||||
gateway_id=eks_igw.id,
|
||||
)],
|
||||
tags={
|
||||
"Name": "pulumi-vpc-rt",
|
||||
})
|
||||
|
@ -51,20 +51,20 @@ eks_security_group = aws.ec2.SecurityGroup("eksSecurityGroup",
|
|||
"Name": "pulumi-cluster-sg",
|
||||
},
|
||||
ingress=[
|
||||
{
|
||||
"cidr_blocks": ["0.0.0.0/0"],
|
||||
"from_port": 443,
|
||||
"to_port": 443,
|
||||
"protocol": "tcp",
|
||||
"description": "Allow pods to communicate with the cluster API Server.",
|
||||
},
|
||||
{
|
||||
"cidr_blocks": ["0.0.0.0/0"],
|
||||
"from_port": 80,
|
||||
"to_port": 80,
|
||||
"protocol": "tcp",
|
||||
"description": "Allow internet access to pods",
|
||||
},
|
||||
aws.ec2.SecurityGroupIngressArgs(
|
||||
cidr_blocks=["0.0.0.0/0"],
|
||||
from_port=443,
|
||||
to_port=443,
|
||||
protocol="tcp",
|
||||
description="Allow pods to communicate with the cluster API Server.",
|
||||
),
|
||||
aws.ec2.SecurityGroupIngressArgs(
|
||||
cidr_blocks=["0.0.0.0/0"],
|
||||
from_port=80,
|
||||
to_port=80,
|
||||
protocol="tcp",
|
||||
description="Allow internet access to pods",
|
||||
),
|
||||
])
|
||||
# EKS Cluster Role
|
||||
eks_role = aws.iam.Role("eksRole", assume_role_policy=json.dumps({
|
||||
|
@ -111,11 +111,11 @@ eks_cluster = aws.eks.Cluster("eksCluster",
|
|||
tags={
|
||||
"Name": "pulumi-eks-cluster",
|
||||
},
|
||||
vpc_config={
|
||||
"publicAccessCidrs": ["0.0.0.0/0"],
|
||||
"security_group_ids": [eks_security_group.id],
|
||||
"subnet_ids": subnet_ids,
|
||||
})
|
||||
vpc_config=aws.eks.ClusterVpcConfigArgs(
|
||||
public_access_cidrs=["0.0.0.0/0"],
|
||||
security_group_ids=[eks_security_group.id],
|
||||
subnet_ids=subnet_ids,
|
||||
))
|
||||
node_group = aws.eks.NodeGroup("nodeGroup",
|
||||
cluster_name=eks_cluster.name,
|
||||
node_group_name="pulumi-eks-nodegroup",
|
||||
|
@ -124,18 +124,18 @@ node_group = aws.eks.NodeGroup("nodeGroup",
|
|||
tags={
|
||||
"Name": "pulumi-cluster-nodeGroup",
|
||||
},
|
||||
scaling_config={
|
||||
"desiredSize": 2,
|
||||
"max_size": 2,
|
||||
"min_size": 1,
|
||||
})
|
||||
scaling_config=aws.eks.NodeGroupScalingConfigArgs(
|
||||
desired_size=2,
|
||||
max_size=2,
|
||||
min_size=1,
|
||||
))
|
||||
pulumi.export("clusterName", eks_cluster.name)
|
||||
pulumi.export("kubeconfig", pulumi.Output.all(eks_cluster.endpoint, eks_cluster.certificate_authority, eks_cluster.name).apply(lambda endpoint, certificate_authority, name: json.dumps({
|
||||
"apiVersion": "v1",
|
||||
"clusters": [{
|
||||
"cluster": {
|
||||
"server": endpoint,
|
||||
"certificate-authority-data": certificate_authority["data"],
|
||||
"certificate-authority-data": certificate_authority.data,
|
||||
},
|
||||
"name": "kubernetes",
|
||||
}],
|
||||
|
|
|
@ -7,18 +7,18 @@ subnets = aws.ec2.get_subnet_ids(vpc_id=vpc.id)
|
|||
# Create a security group that permits HTTP ingress and unrestricted egress.
|
||||
web_security_group = aws.ec2.SecurityGroup("webSecurityGroup",
|
||||
vpc_id=vpc.id,
|
||||
egress=[{
|
||||
"protocol": "-1",
|
||||
"from_port": 0,
|
||||
"to_port": 0,
|
||||
"cidr_blocks": ["0.0.0.0/0"],
|
||||
}],
|
||||
ingress=[{
|
||||
"protocol": "tcp",
|
||||
"from_port": 80,
|
||||
"to_port": 80,
|
||||
"cidr_blocks": ["0.0.0.0/0"],
|
||||
}])
|
||||
egress=[aws.ec2.SecurityGroupEgressArgs(
|
||||
protocol="-1",
|
||||
from_port=0,
|
||||
to_port=0,
|
||||
cidr_blocks=["0.0.0.0/0"],
|
||||
)],
|
||||
ingress=[aws.ec2.SecurityGroupIngressArgs(
|
||||
protocol="tcp",
|
||||
from_port=80,
|
||||
to_port=80,
|
||||
cidr_blocks=["0.0.0.0/0"],
|
||||
)])
|
||||
# Create an ECS cluster to run a container-based service.
|
||||
cluster = aws.ecs.Cluster("cluster")
|
||||
# Create an IAM role that can be used by our service's task.
|
||||
|
@ -48,10 +48,10 @@ web_target_group = aws.elasticloadbalancingv2.TargetGroup("webTargetGroup",
|
|||
web_listener = aws.elasticloadbalancingv2.Listener("webListener",
|
||||
load_balancer_arn=web_load_balancer.arn,
|
||||
port=80,
|
||||
default_actions=[{
|
||||
"type": "forward",
|
||||
"target_group_arn": web_target_group.arn,
|
||||
}])
|
||||
default_actions=[aws.elasticloadbalancingv2.ListenerDefaultActionArgs(
|
||||
type="forward",
|
||||
target_group_arn=web_target_group.arn,
|
||||
)])
|
||||
# Spin up a load balanced service running NGINX
|
||||
app_task = aws.ecs.TaskDefinition("appTask",
|
||||
family="fargate-task-definition",
|
||||
|
@ -74,15 +74,15 @@ app_service = aws.ecs.Service("appService",
|
|||
desired_count=5,
|
||||
launch_type="FARGATE",
|
||||
task_definition=app_task.arn,
|
||||
network_configuration={
|
||||
"assignPublicIp": True,
|
||||
"subnets": subnets.ids,
|
||||
"security_groups": [web_security_group.id],
|
||||
},
|
||||
load_balancers=[{
|
||||
"target_group_arn": web_target_group.arn,
|
||||
"container_name": "my-app",
|
||||
"containerPort": 80,
|
||||
}],
|
||||
network_configuration=aws.ecs.ServiceNetworkConfigurationArgs(
|
||||
assign_public_ip=True,
|
||||
subnets=subnets.ids,
|
||||
security_groups=[web_security_group.id],
|
||||
),
|
||||
load_balancers=[aws.ecs.ServiceLoadBalancerArgs(
|
||||
target_group_arn=web_target_group.arn,
|
||||
container_name="my-app",
|
||||
container_port=80,
|
||||
)],
|
||||
opts=ResourceOptions(depends_on=[web_listener]))
|
||||
pulumi.export("url", web_load_balancer.dns_name)
|
||||
|
|
|
@ -4,9 +4,9 @@ import os
|
|||
import pulumi_aws as aws
|
||||
|
||||
# Create a bucket and expose a website index document
|
||||
site_bucket = aws.s3.Bucket("siteBucket", website={
|
||||
"indexDocument": "index.html",
|
||||
})
|
||||
site_bucket = aws.s3.Bucket("siteBucket", website=aws.s3.BucketWebsiteArgs(
|
||||
index_document="index.html",
|
||||
))
|
||||
site_dir = "www"
|
||||
# For each file in the directory, create an S3 object stored in `siteBucket`
|
||||
files = []
|
||||
|
|
|
@ -2,7 +2,7 @@ import pulumi
|
|||
import pulumi_aws as aws
|
||||
|
||||
logs = aws.s3.Bucket("logs")
|
||||
bucket = aws.s3.Bucket("bucket", loggings=[{
|
||||
"targetBucket": logs.bucket,
|
||||
}])
|
||||
pulumi.export("targetBucket", bucket.loggings[0]["targetBucket"])
|
||||
bucket = aws.s3.Bucket("bucket", loggings=[aws.s3.BucketLoggingArgs(
|
||||
target_bucket=logs.bucket,
|
||||
)])
|
||||
pulumi.export("targetBucket", bucket.loggings[0].target_bucket)
|
||||
|
|
|
@ -2,16 +2,16 @@ import pulumi
|
|||
import pulumi_aws as aws
|
||||
|
||||
# Create a new security group for port 80.
|
||||
security_group = aws.ec2.SecurityGroup("securityGroup", ingress=[{
|
||||
"protocol": "tcp",
|
||||
"from_port": 0,
|
||||
"to_port": 0,
|
||||
"cidr_blocks": ["0.0.0.0/0"],
|
||||
}])
|
||||
ami = aws.get_ami(filters=[{
|
||||
"name": "name",
|
||||
"values": ["amzn-ami-hvm-*-x86_64-ebs"],
|
||||
}],
|
||||
security_group = aws.ec2.SecurityGroup("securityGroup", ingress=[aws.ec2.SecurityGroupIngressArgs(
|
||||
protocol="tcp",
|
||||
from_port=0,
|
||||
to_port=0,
|
||||
cidr_blocks=["0.0.0.0/0"],
|
||||
)])
|
||||
ami = aws.get_ami(filters=[aws.GetAmiFilterArgs(
|
||||
name="name",
|
||||
values=["amzn-ami-hvm-*-x86_64-ebs"],
|
||||
)],
|
||||
owners=["137112412989"],
|
||||
most_recent=True)
|
||||
# Create a simple web server using the startup script for the instance.
|
||||
|
|
5
pkg/codegen/internal/test/testdata/aws.json
vendored
5
pkg/codegen/internal/test/testdata/aws.json
vendored
|
@ -139937,7 +139937,8 @@
|
|||
"readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-aws)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi/pulumi-aws` repo](https://github.com/pulumi/pulumi-aws/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-providers/terraform-provider-aws` repo](https://github.com/terraform-providers/terraform-provider-aws/issues).",
|
||||
"requires": {
|
||||
"pulumi": "\u003e=2.0.0,\u003c3.0.0"
|
||||
}
|
||||
},
|
||||
"usesIOClasses": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
214
pkg/codegen/internal/test/testdata/kubernetes-operator.pp
vendored
Normal file
214
pkg/codegen/internal/test/testdata/kubernetes-operator.pp
vendored
Normal file
|
@ -0,0 +1,214 @@
|
|||
resource pulumi_kubernetes_operatorDeployment "kubernetes:apps/v1:Deployment" {
|
||||
apiVersion = "apps/v1"
|
||||
kind = "Deployment"
|
||||
metadata = {
|
||||
name = "pulumi-kubernetes-operator"
|
||||
}
|
||||
spec = {
|
||||
# Currently only 1 replica supported, until leader election: https://github.com/pulumi/pulumi-kubernetes-operator/issues/33
|
||||
replicas = 1
|
||||
selector = {
|
||||
matchLabels = {
|
||||
name = "pulumi-kubernetes-operator"
|
||||
}
|
||||
}
|
||||
template = {
|
||||
metadata = {
|
||||
labels = {
|
||||
name = "pulumi-kubernetes-operator"
|
||||
}
|
||||
}
|
||||
spec = {
|
||||
serviceAccountName = "pulumi-kubernetes-operator"
|
||||
imagePullSecrets = [
|
||||
{
|
||||
name = "pulumi-kubernetes-operator"
|
||||
}
|
||||
]
|
||||
containers = [
|
||||
{
|
||||
name = "pulumi-kubernetes-operator"
|
||||
image = "pulumi/pulumi-kubernetes-operator:v0.0.2"
|
||||
command = [
|
||||
"pulumi-kubernetes-operator"
|
||||
]
|
||||
args = [
|
||||
"--zap-level=debug"
|
||||
]
|
||||
imagePullPolicy = "Always"
|
||||
env = [
|
||||
{
|
||||
name = "WATCH_NAMESPACE"
|
||||
valueFrom = {
|
||||
fieldRef = {
|
||||
fieldPath = "metadata.namespace"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "POD_NAME"
|
||||
valueFrom = {
|
||||
fieldRef = {
|
||||
fieldPath = "metadata.name"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "OPERATOR_NAME"
|
||||
value = "pulumi-kubernetes-operator"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource pulumi_kubernetes_operatorRole "kubernetes:rbac.authorization.k8s.io/v1:Role" {
|
||||
apiVersion = "rbac.authorization.k8s.io/v1"
|
||||
kind = "Role"
|
||||
metadata = {
|
||||
creationTimestamp = null
|
||||
name = "pulumi-kubernetes-operator"
|
||||
}
|
||||
rules = [
|
||||
{
|
||||
apiGroups = [
|
||||
""
|
||||
]
|
||||
resources = [
|
||||
"pods",
|
||||
"services",
|
||||
"services/finalizers",
|
||||
"endpoints",
|
||||
"persistentvolumeclaims",
|
||||
"events",
|
||||
"configmaps",
|
||||
"secrets"
|
||||
]
|
||||
verbs = [
|
||||
"create",
|
||||
"delete",
|
||||
"get",
|
||||
"list",
|
||||
"patch",
|
||||
"update",
|
||||
"watch"
|
||||
]
|
||||
},
|
||||
{
|
||||
apiGroups = [
|
||||
"apps"
|
||||
]
|
||||
resources = [
|
||||
"deployments",
|
||||
"daemonsets",
|
||||
"replicasets",
|
||||
"statefulsets"
|
||||
]
|
||||
verbs = [
|
||||
"create",
|
||||
"delete",
|
||||
"get",
|
||||
"list",
|
||||
"patch",
|
||||
"update",
|
||||
"watch"
|
||||
]
|
||||
},
|
||||
{
|
||||
apiGroups = [
|
||||
"monitoring.coreos.com"
|
||||
]
|
||||
resources = [
|
||||
"servicemonitors"
|
||||
]
|
||||
verbs = [
|
||||
"get",
|
||||
"create"
|
||||
]
|
||||
},
|
||||
{
|
||||
apiGroups = [
|
||||
"apps"
|
||||
]
|
||||
resourceNames = [
|
||||
"pulumi-kubernetes-operator"
|
||||
]
|
||||
resources = [
|
||||
"deployments/finalizers"
|
||||
]
|
||||
verbs = [
|
||||
"update"
|
||||
]
|
||||
},
|
||||
{
|
||||
apiGroups = [
|
||||
""
|
||||
]
|
||||
resources = [
|
||||
"pods"
|
||||
]
|
||||
verbs = [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
{
|
||||
apiGroups = [
|
||||
"apps"
|
||||
]
|
||||
resources = [
|
||||
"replicasets",
|
||||
"deployments"
|
||||
]
|
||||
verbs = [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
{
|
||||
apiGroups = [
|
||||
"pulumi.com"
|
||||
]
|
||||
resources = [
|
||||
"*"
|
||||
]
|
||||
verbs = [
|
||||
"create",
|
||||
"delete",
|
||||
"get",
|
||||
"list",
|
||||
"patch",
|
||||
"update",
|
||||
"watch"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
resource pulumi_kubernetes_operatorRoleBinding "kubernetes:rbac.authorization.k8s.io/v1:RoleBinding" {
|
||||
kind = "RoleBinding"
|
||||
apiVersion = "rbac.authorization.k8s.io/v1"
|
||||
metadata = {
|
||||
name = "pulumi-kubernetes-operator"
|
||||
}
|
||||
subjects = [
|
||||
{
|
||||
kind = "ServiceAccount"
|
||||
name = "pulumi-kubernetes-operator"
|
||||
}
|
||||
]
|
||||
roleRef = {
|
||||
kind = "Role"
|
||||
name = "pulumi-kubernetes-operator"
|
||||
apiGroup = "rbac.authorization.k8s.io"
|
||||
}
|
||||
}
|
||||
|
||||
resource pulumi_kubernetes_operatorServiceAccount "kubernetes:core/v1:ServiceAccount" {
|
||||
apiVersion = "v1"
|
||||
kind = "ServiceAccount"
|
||||
metadata = {
|
||||
name = "pulumi-kubernetes-operator"
|
||||
}
|
||||
}
|
282
pkg/codegen/internal/test/testdata/kubernetes-operator.pp.cs
vendored
Normal file
282
pkg/codegen/internal/test/testdata/kubernetes-operator.pp.cs
vendored
Normal file
|
@ -0,0 +1,282 @@
|
|||
using Pulumi;
|
||||
using Kubernetes = Pulumi.Kubernetes;
|
||||
|
||||
class MyStack : Stack
|
||||
{
|
||||
public MyStack()
|
||||
{
|
||||
var pulumi_kubernetes_operatorDeployment = new Kubernetes.Apps.V1.Deployment("pulumi_kubernetes_operatorDeployment", new Kubernetes.Types.Inputs.Apps.V1.DeploymentArgs
|
||||
{
|
||||
ApiVersion = "apps/v1",
|
||||
Kind = "Deployment",
|
||||
Metadata = new Kubernetes.Types.Inputs.Meta.V1.ObjectMetaArgs
|
||||
{
|
||||
Name = "pulumi-kubernetes-operator",
|
||||
},
|
||||
Spec = new Kubernetes.Types.Inputs.Apps.V1.DeploymentSpecArgs
|
||||
{
|
||||
Replicas = 1,
|
||||
Selector = new Kubernetes.Types.Inputs.Meta.V1.LabelSelectorArgs
|
||||
{
|
||||
MatchLabels =
|
||||
{
|
||||
{ "name", "pulumi-kubernetes-operator" },
|
||||
},
|
||||
},
|
||||
Template = new Kubernetes.Types.Inputs.Core.V1.PodTemplateSpecArgs
|
||||
{
|
||||
Metadata = new Kubernetes.Types.Inputs.Meta.V1.ObjectMetaArgs
|
||||
{
|
||||
Labels =
|
||||
{
|
||||
{ "name", "pulumi-kubernetes-operator" },
|
||||
},
|
||||
},
|
||||
Spec = new Kubernetes.Types.Inputs.Core.V1.PodSpecArgs
|
||||
{
|
||||
ServiceAccountName = "pulumi-kubernetes-operator",
|
||||
ImagePullSecrets =
|
||||
{
|
||||
new Kubernetes.Types.Inputs.Core.V1.LocalObjectReferenceArgs
|
||||
{
|
||||
Name = "pulumi-kubernetes-operator",
|
||||
},
|
||||
},
|
||||
Containers =
|
||||
{
|
||||
new Kubernetes.Types.Inputs.Core.V1.ContainerArgs
|
||||
{
|
||||
Name = "pulumi-kubernetes-operator",
|
||||
Image = "pulumi/pulumi-kubernetes-operator:v0.0.2",
|
||||
Command =
|
||||
{
|
||||
"pulumi-kubernetes-operator",
|
||||
},
|
||||
Args =
|
||||
{
|
||||
"--zap-level=debug",
|
||||
},
|
||||
ImagePullPolicy = "Always",
|
||||
Env =
|
||||
{
|
||||
new Kubernetes.Types.Inputs.Core.V1.EnvVarArgs
|
||||
{
|
||||
Name = "WATCH_NAMESPACE",
|
||||
ValueFrom = new Kubernetes.Types.Inputs.Core.V1.EnvVarSourceArgs
|
||||
{
|
||||
FieldRef = new Kubernetes.Types.Inputs.Core.V1.ObjectFieldSelectorArgs
|
||||
{
|
||||
FieldPath = "metadata.namespace",
|
||||
},
|
||||
},
|
||||
},
|
||||
new Kubernetes.Types.Inputs.Core.V1.EnvVarArgs
|
||||
{
|
||||
Name = "POD_NAME",
|
||||
ValueFrom = new Kubernetes.Types.Inputs.Core.V1.EnvVarSourceArgs
|
||||
{
|
||||
FieldRef = new Kubernetes.Types.Inputs.Core.V1.ObjectFieldSelectorArgs
|
||||
{
|
||||
FieldPath = "metadata.name",
|
||||
},
|
||||
},
|
||||
},
|
||||
new Kubernetes.Types.Inputs.Core.V1.EnvVarArgs
|
||||
{
|
||||
Name = "OPERATOR_NAME",
|
||||
Value = "pulumi-kubernetes-operator",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
var pulumi_kubernetes_operatorRole = new Kubernetes.Rbac.V1.Role("pulumi_kubernetes_operatorRole", new Kubernetes.Types.Inputs.Rbac.V1.RoleArgs
|
||||
{
|
||||
ApiVersion = "rbac.authorization.k8s.io/v1",
|
||||
Kind = "Role",
|
||||
Metadata = new Kubernetes.Types.Inputs.Meta.V1.ObjectMetaArgs
|
||||
{
|
||||
CreationTimestamp = null,
|
||||
Name = "pulumi-kubernetes-operator",
|
||||
},
|
||||
Rules =
|
||||
{
|
||||
new Kubernetes.Types.Inputs.Rbac.V1.PolicyRuleArgs
|
||||
{
|
||||
ApiGroups =
|
||||
{
|
||||
"",
|
||||
},
|
||||
Resources =
|
||||
{
|
||||
"pods",
|
||||
"services",
|
||||
"services/finalizers",
|
||||
"endpoints",
|
||||
"persistentvolumeclaims",
|
||||
"events",
|
||||
"configmaps",
|
||||
"secrets",
|
||||
},
|
||||
Verbs =
|
||||
{
|
||||
"create",
|
||||
"delete",
|
||||
"get",
|
||||
"list",
|
||||
"patch",
|
||||
"update",
|
||||
"watch",
|
||||
},
|
||||
},
|
||||
new Kubernetes.Types.Inputs.Rbac.V1.PolicyRuleArgs
|
||||
{
|
||||
ApiGroups =
|
||||
{
|
||||
"apps",
|
||||
},
|
||||
Resources =
|
||||
{
|
||||
"deployments",
|
||||
"daemonsets",
|
||||
"replicasets",
|
||||
"statefulsets",
|
||||
},
|
||||
Verbs =
|
||||
{
|
||||
"create",
|
||||
"delete",
|
||||
"get",
|
||||
"list",
|
||||
"patch",
|
||||
"update",
|
||||
"watch",
|
||||
},
|
||||
},
|
||||
new Kubernetes.Types.Inputs.Rbac.V1.PolicyRuleArgs
|
||||
{
|
||||
ApiGroups =
|
||||
{
|
||||
"monitoring.coreos.com",
|
||||
},
|
||||
Resources =
|
||||
{
|
||||
"servicemonitors",
|
||||
},
|
||||
Verbs =
|
||||
{
|
||||
"get",
|
||||
"create",
|
||||
},
|
||||
},
|
||||
new Kubernetes.Types.Inputs.Rbac.V1.PolicyRuleArgs
|
||||
{
|
||||
ApiGroups =
|
||||
{
|
||||
"apps",
|
||||
},
|
||||
ResourceNames =
|
||||
{
|
||||
"pulumi-kubernetes-operator",
|
||||
},
|
||||
Resources =
|
||||
{
|
||||
"deployments/finalizers",
|
||||
},
|
||||
Verbs =
|
||||
{
|
||||
"update",
|
||||
},
|
||||
},
|
||||
new Kubernetes.Types.Inputs.Rbac.V1.PolicyRuleArgs
|
||||
{
|
||||
ApiGroups =
|
||||
{
|
||||
"",
|
||||
},
|
||||
Resources =
|
||||
{
|
||||
"pods",
|
||||
},
|
||||
Verbs =
|
||||
{
|
||||
"get",
|
||||
},
|
||||
},
|
||||
new Kubernetes.Types.Inputs.Rbac.V1.PolicyRuleArgs
|
||||
{
|
||||
ApiGroups =
|
||||
{
|
||||
"apps",
|
||||
},
|
||||
Resources =
|
||||
{
|
||||
"replicasets",
|
||||
"deployments",
|
||||
},
|
||||
Verbs =
|
||||
{
|
||||
"get",
|
||||
},
|
||||
},
|
||||
new Kubernetes.Types.Inputs.Rbac.V1.PolicyRuleArgs
|
||||
{
|
||||
ApiGroups =
|
||||
{
|
||||
"pulumi.com",
|
||||
},
|
||||
Resources =
|
||||
{
|
||||
"*",
|
||||
},
|
||||
Verbs =
|
||||
{
|
||||
"create",
|
||||
"delete",
|
||||
"get",
|
||||
"list",
|
||||
"patch",
|
||||
"update",
|
||||
"watch",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
var pulumi_kubernetes_operatorRoleBinding = new Kubernetes.Rbac.V1.RoleBinding("pulumi_kubernetes_operatorRoleBinding", new Kubernetes.Types.Inputs.Rbac.V1.RoleBindingArgs
|
||||
{
|
||||
Kind = "RoleBinding",
|
||||
ApiVersion = "rbac.authorization.k8s.io/v1",
|
||||
Metadata = new Kubernetes.Types.Inputs.Meta.V1.ObjectMetaArgs
|
||||
{
|
||||
Name = "pulumi-kubernetes-operator",
|
||||
},
|
||||
Subjects =
|
||||
{
|
||||
new Kubernetes.Types.Inputs.Rbac.V1.SubjectArgs
|
||||
{
|
||||
Kind = "ServiceAccount",
|
||||
Name = "pulumi-kubernetes-operator",
|
||||
},
|
||||
},
|
||||
RoleRef = new Kubernetes.Types.Inputs.Rbac.V1.RoleRefArgs
|
||||
{
|
||||
Kind = "Role",
|
||||
Name = "pulumi-kubernetes-operator",
|
||||
ApiGroup = "rbac.authorization.k8s.io",
|
||||
},
|
||||
});
|
||||
var pulumi_kubernetes_operatorServiceAccount = new Kubernetes.Core.V1.ServiceAccount("pulumi_kubernetes_operatorServiceAccount", new Kubernetes.Types.Inputs.Core.V1.ServiceAccountArgs
|
||||
{
|
||||
ApiVersion = "v1",
|
||||
Kind = "ServiceAccount",
|
||||
Metadata = new Kubernetes.Types.Inputs.Meta.V1.ObjectMetaArgs
|
||||
{
|
||||
Name = "pulumi-kubernetes-operator",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
}
|
237
pkg/codegen/internal/test/testdata/kubernetes-operator.pp.go
vendored
Normal file
237
pkg/codegen/internal/test/testdata/kubernetes-operator.pp.go
vendored
Normal file
|
@ -0,0 +1,237 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
appsv1 "github.com/pulumi/pulumi-kubernetes/sdk/v2/go/kubernetes/apps/v1"
|
||||
corev1 "github.com/pulumi/pulumi-kubernetes/sdk/v2/go/kubernetes/core/v1"
|
||||
metav1 "github.com/pulumi/pulumi-kubernetes/sdk/v2/go/kubernetes/meta/v1"
|
||||
rbacv1 "github.com/pulumi/pulumi-kubernetes/sdk/v2/go/kubernetes/rbac/v1"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/pulumi"
|
||||
)
|
||||
|
||||
func main() {
|
||||
pulumi.Run(func(ctx *pulumi.Context) error {
|
||||
_, err := appsv1.NewDeployment(ctx, "pulumi_kubernetes_operatorDeployment", &appsv1.DeploymentArgs{
|
||||
ApiVersion: pulumi.String("apps/v1"),
|
||||
Kind: pulumi.String("Deployment"),
|
||||
Metadata: &metav1.ObjectMetaArgs{
|
||||
Name: pulumi.String("pulumi-kubernetes-operator"),
|
||||
},
|
||||
Spec: &appsv1.DeploymentSpecArgs{
|
||||
Replicas: pulumi.Int(1),
|
||||
Selector: &metav1.LabelSelectorArgs{
|
||||
MatchLabels: pulumi.StringMap{
|
||||
"name": pulumi.String("pulumi-kubernetes-operator"),
|
||||
},
|
||||
},
|
||||
Template: &corev1.PodTemplateSpecArgs{
|
||||
Metadata: &metav1.ObjectMetaArgs{
|
||||
Labels: pulumi.StringMap{
|
||||
"name": pulumi.String("pulumi-kubernetes-operator"),
|
||||
},
|
||||
},
|
||||
Spec: &corev1.PodSpecArgs{
|
||||
ServiceAccountName: pulumi.String("pulumi-kubernetes-operator"),
|
||||
ImagePullSecrets: corev1.LocalObjectReferenceArray{
|
||||
&corev1.LocalObjectReferenceArgs{
|
||||
Name: pulumi.String("pulumi-kubernetes-operator"),
|
||||
},
|
||||
},
|
||||
Containers: corev1.ContainerArray{
|
||||
&corev1.ContainerArgs{
|
||||
Name: pulumi.String("pulumi-kubernetes-operator"),
|
||||
Image: pulumi.String("pulumi/pulumi-kubernetes-operator:v0.0.2"),
|
||||
Command: pulumi.StringArray{
|
||||
pulumi.String("pulumi-kubernetes-operator"),
|
||||
},
|
||||
Args: pulumi.StringArray{
|
||||
pulumi.String("--zap-level=debug"),
|
||||
},
|
||||
ImagePullPolicy: pulumi.String("Always"),
|
||||
Env: corev1.EnvVarArray{
|
||||
&corev1.EnvVarArgs{
|
||||
Name: pulumi.String("WATCH_NAMESPACE"),
|
||||
ValueFrom: &corev1.EnvVarSourceArgs{
|
||||
FieldRef: &corev1.ObjectFieldSelectorArgs{
|
||||
FieldPath: pulumi.String("metadata.namespace"),
|
||||
},
|
||||
},
|
||||
},
|
||||
&corev1.EnvVarArgs{
|
||||
Name: pulumi.String("POD_NAME"),
|
||||
ValueFrom: &corev1.EnvVarSourceArgs{
|
||||
FieldRef: &corev1.ObjectFieldSelectorArgs{
|
||||
FieldPath: pulumi.String("metadata.name"),
|
||||
},
|
||||
},
|
||||
},
|
||||
&corev1.EnvVarArgs{
|
||||
Name: pulumi.String("OPERATOR_NAME"),
|
||||
Value: pulumi.String("pulumi-kubernetes-operator"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = rbacv1.NewRole(ctx, "pulumi_kubernetes_operatorRole", &rbacv1.RoleArgs{
|
||||
ApiVersion: pulumi.String("rbac.authorization.k8s.io/v1"),
|
||||
Kind: pulumi.String("Role"),
|
||||
Metadata: &metav1.ObjectMetaArgs{
|
||||
CreationTimestamp: nil,
|
||||
Name: pulumi.String("pulumi-kubernetes-operator"),
|
||||
},
|
||||
Rules: rbacv1.PolicyRuleArray{
|
||||
&rbacv1.PolicyRuleArgs{
|
||||
ApiGroups: pulumi.StringArray{
|
||||
pulumi.String(""),
|
||||
},
|
||||
Resources: pulumi.StringArray{
|
||||
pulumi.String("pods"),
|
||||
pulumi.String("services"),
|
||||
pulumi.String("services/finalizers"),
|
||||
pulumi.String("endpoints"),
|
||||
pulumi.String("persistentvolumeclaims"),
|
||||
pulumi.String("events"),
|
||||
pulumi.String("configmaps"),
|
||||
pulumi.String("secrets"),
|
||||
},
|
||||
Verbs: pulumi.StringArray{
|
||||
pulumi.String("create"),
|
||||
pulumi.String("delete"),
|
||||
pulumi.String("get"),
|
||||
pulumi.String("list"),
|
||||
pulumi.String("patch"),
|
||||
pulumi.String("update"),
|
||||
pulumi.String("watch"),
|
||||
},
|
||||
},
|
||||
&rbacv1.PolicyRuleArgs{
|
||||
ApiGroups: pulumi.StringArray{
|
||||
pulumi.String("apps"),
|
||||
},
|
||||
Resources: pulumi.StringArray{
|
||||
pulumi.String("deployments"),
|
||||
pulumi.String("daemonsets"),
|
||||
pulumi.String("replicasets"),
|
||||
pulumi.String("statefulsets"),
|
||||
},
|
||||
Verbs: pulumi.StringArray{
|
||||
pulumi.String("create"),
|
||||
pulumi.String("delete"),
|
||||
pulumi.String("get"),
|
||||
pulumi.String("list"),
|
||||
pulumi.String("patch"),
|
||||
pulumi.String("update"),
|
||||
pulumi.String("watch"),
|
||||
},
|
||||
},
|
||||
&rbacv1.PolicyRuleArgs{
|
||||
ApiGroups: pulumi.StringArray{
|
||||
pulumi.String("monitoring.coreos.com"),
|
||||
},
|
||||
Resources: pulumi.StringArray{
|
||||
pulumi.String("servicemonitors"),
|
||||
},
|
||||
Verbs: pulumi.StringArray{
|
||||
pulumi.String("get"),
|
||||
pulumi.String("create"),
|
||||
},
|
||||
},
|
||||
&rbacv1.PolicyRuleArgs{
|
||||
ApiGroups: pulumi.StringArray{
|
||||
pulumi.String("apps"),
|
||||
},
|
||||
ResourceNames: pulumi.StringArray{
|
||||
pulumi.String("pulumi-kubernetes-operator"),
|
||||
},
|
||||
Resources: pulumi.StringArray{
|
||||
pulumi.String("deployments/finalizers"),
|
||||
},
|
||||
Verbs: pulumi.StringArray{
|
||||
pulumi.String("update"),
|
||||
},
|
||||
},
|
||||
&rbacv1.PolicyRuleArgs{
|
||||
ApiGroups: pulumi.StringArray{
|
||||
pulumi.String(""),
|
||||
},
|
||||
Resources: pulumi.StringArray{
|
||||
pulumi.String("pods"),
|
||||
},
|
||||
Verbs: pulumi.StringArray{
|
||||
pulumi.String("get"),
|
||||
},
|
||||
},
|
||||
&rbacv1.PolicyRuleArgs{
|
||||
ApiGroups: pulumi.StringArray{
|
||||
pulumi.String("apps"),
|
||||
},
|
||||
Resources: pulumi.StringArray{
|
||||
pulumi.String("replicasets"),
|
||||
pulumi.String("deployments"),
|
||||
},
|
||||
Verbs: pulumi.StringArray{
|
||||
pulumi.String("get"),
|
||||
},
|
||||
},
|
||||
&rbacv1.PolicyRuleArgs{
|
||||
ApiGroups: pulumi.StringArray{
|
||||
pulumi.String("pulumi.com"),
|
||||
},
|
||||
Resources: pulumi.StringArray{
|
||||
pulumi.String("*"),
|
||||
},
|
||||
Verbs: pulumi.StringArray{
|
||||
pulumi.String("create"),
|
||||
pulumi.String("delete"),
|
||||
pulumi.String("get"),
|
||||
pulumi.String("list"),
|
||||
pulumi.String("patch"),
|
||||
pulumi.String("update"),
|
||||
pulumi.String("watch"),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = rbacv1.NewRoleBinding(ctx, "pulumi_kubernetes_operatorRoleBinding", &rbacv1.RoleBindingArgs{
|
||||
Kind: pulumi.String("RoleBinding"),
|
||||
ApiVersion: pulumi.String("rbac.authorization.k8s.io/v1"),
|
||||
Metadata: &metav1.ObjectMetaArgs{
|
||||
Name: pulumi.String("pulumi-kubernetes-operator"),
|
||||
},
|
||||
Subjects: rbacv1.SubjectArray{
|
||||
&rbacv1.SubjectArgs{
|
||||
Kind: pulumi.String("ServiceAccount"),
|
||||
Name: pulumi.String("pulumi-kubernetes-operator"),
|
||||
},
|
||||
},
|
||||
RoleRef: &rbacv1.RoleRefArgs{
|
||||
Kind: pulumi.String("Role"),
|
||||
Name: pulumi.String("pulumi-kubernetes-operator"),
|
||||
ApiGroup: pulumi.String("rbac.authorization.k8s.io"),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = corev1.NewServiceAccount(ctx, "pulumi_kubernetes_operatorServiceAccount", &corev1.ServiceAccountArgs{
|
||||
ApiVersion: pulumi.String("v1"),
|
||||
Kind: pulumi.String("ServiceAccount"),
|
||||
Metadata: &metav1.ObjectMetaArgs{
|
||||
Name: pulumi.String("pulumi-kubernetes-operator"),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
169
pkg/codegen/internal/test/testdata/kubernetes-operator.pp.py
vendored
Normal file
169
pkg/codegen/internal/test/testdata/kubernetes-operator.pp.py
vendored
Normal file
|
@ -0,0 +1,169 @@
|
|||
import pulumi
|
||||
import pulumi_kubernetes as kubernetes
|
||||
|
||||
pulumi_kubernetes_operator_deployment = kubernetes.apps.v1.Deployment("pulumi_kubernetes_operatorDeployment",
|
||||
api_version="apps/v1",
|
||||
kind="Deployment",
|
||||
metadata={
|
||||
"name": "pulumi-kubernetes-operator",
|
||||
},
|
||||
spec={
|
||||
"replicas": 1,
|
||||
"selector": {
|
||||
"match_labels": {
|
||||
"name": "pulumi-kubernetes-operator",
|
||||
},
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"name": "pulumi-kubernetes-operator",
|
||||
},
|
||||
},
|
||||
"spec": {
|
||||
"service_account_name": "pulumi-kubernetes-operator",
|
||||
"image_pull_secrets": [{
|
||||
"name": "pulumi-kubernetes-operator",
|
||||
}],
|
||||
"containers": [{
|
||||
"name": "pulumi-kubernetes-operator",
|
||||
"image": "pulumi/pulumi-kubernetes-operator:v0.0.2",
|
||||
"command": ["pulumi-kubernetes-operator"],
|
||||
"args": ["--zap-level=debug"],
|
||||
"image_pull_policy": "Always",
|
||||
"env": [
|
||||
{
|
||||
"name": "WATCH_NAMESPACE",
|
||||
"value_from": {
|
||||
"field_ref": {
|
||||
"field_path": "metadata.namespace",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "POD_NAME",
|
||||
"value_from": {
|
||||
"field_ref": {
|
||||
"field_path": "metadata.name",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "OPERATOR_NAME",
|
||||
"value": "pulumi-kubernetes-operator",
|
||||
},
|
||||
],
|
||||
}],
|
||||
},
|
||||
},
|
||||
})
|
||||
pulumi_kubernetes_operator_role = kubernetes.rbac.v1.Role("pulumi_kubernetes_operatorRole",
|
||||
api_version="rbac.authorization.k8s.io/v1",
|
||||
kind="Role",
|
||||
metadata={
|
||||
"creation_timestamp": None,
|
||||
"name": "pulumi-kubernetes-operator",
|
||||
},
|
||||
rules=[
|
||||
{
|
||||
"api_groups": [""],
|
||||
"resources": [
|
||||
"pods",
|
||||
"services",
|
||||
"services/finalizers",
|
||||
"endpoints",
|
||||
"persistentvolumeclaims",
|
||||
"events",
|
||||
"configmaps",
|
||||
"secrets",
|
||||
],
|
||||
"verbs": [
|
||||
"create",
|
||||
"delete",
|
||||
"get",
|
||||
"list",
|
||||
"patch",
|
||||
"update",
|
||||
"watch",
|
||||
],
|
||||
},
|
||||
{
|
||||
"api_groups": ["apps"],
|
||||
"resources": [
|
||||
"deployments",
|
||||
"daemonsets",
|
||||
"replicasets",
|
||||
"statefulsets",
|
||||
],
|
||||
"verbs": [
|
||||
"create",
|
||||
"delete",
|
||||
"get",
|
||||
"list",
|
||||
"patch",
|
||||
"update",
|
||||
"watch",
|
||||
],
|
||||
},
|
||||
{
|
||||
"api_groups": ["monitoring.coreos.com"],
|
||||
"resources": ["servicemonitors"],
|
||||
"verbs": [
|
||||
"get",
|
||||
"create",
|
||||
],
|
||||
},
|
||||
{
|
||||
"api_groups": ["apps"],
|
||||
"resource_names": ["pulumi-kubernetes-operator"],
|
||||
"resources": ["deployments/finalizers"],
|
||||
"verbs": ["update"],
|
||||
},
|
||||
{
|
||||
"api_groups": [""],
|
||||
"resources": ["pods"],
|
||||
"verbs": ["get"],
|
||||
},
|
||||
{
|
||||
"api_groups": ["apps"],
|
||||
"resources": [
|
||||
"replicasets",
|
||||
"deployments",
|
||||
],
|
||||
"verbs": ["get"],
|
||||
},
|
||||
{
|
||||
"api_groups": ["pulumi.com"],
|
||||
"resources": ["*"],
|
||||
"verbs": [
|
||||
"create",
|
||||
"delete",
|
||||
"get",
|
||||
"list",
|
||||
"patch",
|
||||
"update",
|
||||
"watch",
|
||||
],
|
||||
},
|
||||
])
|
||||
pulumi_kubernetes_operator_role_binding = kubernetes.rbac.v1.RoleBinding("pulumi_kubernetes_operatorRoleBinding",
|
||||
kind="RoleBinding",
|
||||
api_version="rbac.authorization.k8s.io/v1",
|
||||
metadata={
|
||||
"name": "pulumi-kubernetes-operator",
|
||||
},
|
||||
subjects=[{
|
||||
"kind": "ServiceAccount",
|
||||
"name": "pulumi-kubernetes-operator",
|
||||
}],
|
||||
role_ref={
|
||||
"kind": "Role",
|
||||
"name": "pulumi-kubernetes-operator",
|
||||
"api_group": "rbac.authorization.k8s.io",
|
||||
})
|
||||
pulumi_kubernetes_operator_service_account = kubernetes.core.v1.ServiceAccount("pulumi_kubernetes_operatorServiceAccount",
|
||||
api_version="v1",
|
||||
kind="ServiceAccount",
|
||||
metadata={
|
||||
"name": "pulumi-kubernetes-operator",
|
||||
})
|
173
pkg/codegen/internal/test/testdata/kubernetes-operator.pp.ts
vendored
Normal file
173
pkg/codegen/internal/test/testdata/kubernetes-operator.pp.ts
vendored
Normal file
|
@ -0,0 +1,173 @@
|
|||
import * as pulumi from "@pulumi/pulumi";
|
||||
import * as kubernetes from "@pulumi/kubernetes";
|
||||
|
||||
const pulumi_kubernetes_operatorDeployment = new kubernetes.apps.v1.Deployment("pulumi_kubernetes_operatorDeployment", {
|
||||
apiVersion: "apps/v1",
|
||||
kind: "Deployment",
|
||||
metadata: {
|
||||
name: "pulumi-kubernetes-operator",
|
||||
},
|
||||
spec: {
|
||||
replicas: 1,
|
||||
selector: {
|
||||
matchLabels: {
|
||||
name: "pulumi-kubernetes-operator",
|
||||
},
|
||||
},
|
||||
template: {
|
||||
metadata: {
|
||||
labels: {
|
||||
name: "pulumi-kubernetes-operator",
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
serviceAccountName: "pulumi-kubernetes-operator",
|
||||
imagePullSecrets: [{
|
||||
name: "pulumi-kubernetes-operator",
|
||||
}],
|
||||
containers: [{
|
||||
name: "pulumi-kubernetes-operator",
|
||||
image: "pulumi/pulumi-kubernetes-operator:v0.0.2",
|
||||
command: ["pulumi-kubernetes-operator"],
|
||||
args: ["--zap-level=debug"],
|
||||
imagePullPolicy: "Always",
|
||||
env: [
|
||||
{
|
||||
name: "WATCH_NAMESPACE",
|
||||
valueFrom: {
|
||||
fieldRef: {
|
||||
fieldPath: "metadata.namespace",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "POD_NAME",
|
||||
valueFrom: {
|
||||
fieldRef: {
|
||||
fieldPath: "metadata.name",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OPERATOR_NAME",
|
||||
value: "pulumi-kubernetes-operator",
|
||||
},
|
||||
],
|
||||
}],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const pulumi_kubernetes_operatorRole = new kubernetes.rbac.v1.Role("pulumi_kubernetes_operatorRole", {
|
||||
apiVersion: "rbac.authorization.k8s.io/v1",
|
||||
kind: "Role",
|
||||
metadata: {
|
||||
creationTimestamp: undefined,
|
||||
name: "pulumi-kubernetes-operator",
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
apiGroups: [""],
|
||||
resources: [
|
||||
"pods",
|
||||
"services",
|
||||
"services/finalizers",
|
||||
"endpoints",
|
||||
"persistentvolumeclaims",
|
||||
"events",
|
||||
"configmaps",
|
||||
"secrets",
|
||||
],
|
||||
verbs: [
|
||||
"create",
|
||||
"delete",
|
||||
"get",
|
||||
"list",
|
||||
"patch",
|
||||
"update",
|
||||
"watch",
|
||||
],
|
||||
},
|
||||
{
|
||||
apiGroups: ["apps"],
|
||||
resources: [
|
||||
"deployments",
|
||||
"daemonsets",
|
||||
"replicasets",
|
||||
"statefulsets",
|
||||
],
|
||||
verbs: [
|
||||
"create",
|
||||
"delete",
|
||||
"get",
|
||||
"list",
|
||||
"patch",
|
||||
"update",
|
||||
"watch",
|
||||
],
|
||||
},
|
||||
{
|
||||
apiGroups: ["monitoring.coreos.com"],
|
||||
resources: ["servicemonitors"],
|
||||
verbs: [
|
||||
"get",
|
||||
"create",
|
||||
],
|
||||
},
|
||||
{
|
||||
apiGroups: ["apps"],
|
||||
resourceNames: ["pulumi-kubernetes-operator"],
|
||||
resources: ["deployments/finalizers"],
|
||||
verbs: ["update"],
|
||||
},
|
||||
{
|
||||
apiGroups: [""],
|
||||
resources: ["pods"],
|
||||
verbs: ["get"],
|
||||
},
|
||||
{
|
||||
apiGroups: ["apps"],
|
||||
resources: [
|
||||
"replicasets",
|
||||
"deployments",
|
||||
],
|
||||
verbs: ["get"],
|
||||
},
|
||||
{
|
||||
apiGroups: ["pulumi.com"],
|
||||
resources: ["*"],
|
||||
verbs: [
|
||||
"create",
|
||||
"delete",
|
||||
"get",
|
||||
"list",
|
||||
"patch",
|
||||
"update",
|
||||
"watch",
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
const pulumi_kubernetes_operatorRoleBinding = new kubernetes.rbac.v1.RoleBinding("pulumi_kubernetes_operatorRoleBinding", {
|
||||
kind: "RoleBinding",
|
||||
apiVersion: "rbac.authorization.k8s.io/v1",
|
||||
metadata: {
|
||||
name: "pulumi-kubernetes-operator",
|
||||
},
|
||||
subjects: [{
|
||||
kind: "ServiceAccount",
|
||||
name: "pulumi-kubernetes-operator",
|
||||
}],
|
||||
roleRef: {
|
||||
kind: "Role",
|
||||
name: "pulumi-kubernetes-operator",
|
||||
apiGroup: "rbac.authorization.k8s.io",
|
||||
},
|
||||
});
|
||||
const pulumi_kubernetes_operatorServiceAccount = new kubernetes.core.v1.ServiceAccount("pulumi_kubernetes_operatorServiceAccount", {
|
||||
apiVersion: "v1",
|
||||
kind: "ServiceAccount",
|
||||
metadata: {
|
||||
name: "pulumi-kubernetes-operator",
|
||||
},
|
||||
});
|
22
pkg/codegen/internal/test/testdata/kubernetes-pod.pp
vendored
Normal file
22
pkg/codegen/internal/test/testdata/kubernetes-pod.pp
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
resource bar "kubernetes:core/v1:Pod" {
|
||||
apiVersion = "v1"
|
||||
kind = "Pod"
|
||||
metadata = {
|
||||
namespace = "foo"
|
||||
name = "bar"
|
||||
}
|
||||
spec = {
|
||||
containers = [
|
||||
{
|
||||
name = "nginx"
|
||||
image = "nginx:1.14-alpine"
|
||||
resources = {
|
||||
limits = {
|
||||
memory = "20Mi"
|
||||
cpu = 0.2
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
39
pkg/codegen/internal/test/testdata/kubernetes-pod.pp.cs
vendored
Normal file
39
pkg/codegen/internal/test/testdata/kubernetes-pod.pp.cs
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
using Pulumi;
|
||||
using Kubernetes = Pulumi.Kubernetes;
|
||||
|
||||
class MyStack : Stack
|
||||
{
|
||||
public MyStack()
|
||||
{
|
||||
var bar = new Kubernetes.Core.V1.Pod("bar", new Kubernetes.Types.Inputs.Core.V1.PodArgs
|
||||
{
|
||||
ApiVersion = "v1",
|
||||
Kind = "Pod",
|
||||
Metadata = new Kubernetes.Types.Inputs.Meta.V1.ObjectMetaArgs
|
||||
{
|
||||
Namespace = "foo",
|
||||
Name = "bar",
|
||||
},
|
||||
Spec = new Kubernetes.Types.Inputs.Core.V1.PodSpecArgs
|
||||
{
|
||||
Containers =
|
||||
{
|
||||
new Kubernetes.Types.Inputs.Core.V1.ContainerArgs
|
||||
{
|
||||
Name = "nginx",
|
||||
Image = "nginx:1.14-alpine",
|
||||
Resources = new Kubernetes.Types.Inputs.Core.V1.ResourceRequirementsArgs
|
||||
{
|
||||
Limits =
|
||||
{
|
||||
{ "memory", "20Mi" },
|
||||
{ "cpu", "0.2" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
}
|
38
pkg/codegen/internal/test/testdata/kubernetes-pod.pp.go
vendored
Normal file
38
pkg/codegen/internal/test/testdata/kubernetes-pod.pp.go
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
corev1 "github.com/pulumi/pulumi-kubernetes/sdk/v2/go/kubernetes/core/v1"
|
||||
metav1 "github.com/pulumi/pulumi-kubernetes/sdk/v2/go/kubernetes/meta/v1"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/pulumi"
|
||||
)
|
||||
|
||||
func main() {
|
||||
pulumi.Run(func(ctx *pulumi.Context) error {
|
||||
_, err := corev1.NewPod(ctx, "bar", &corev1.PodArgs{
|
||||
ApiVersion: pulumi.String("v1"),
|
||||
Kind: pulumi.String("Pod"),
|
||||
Metadata: &metav1.ObjectMetaArgs{
|
||||
Namespace: pulumi.String("foo"),
|
||||
Name: pulumi.String("bar"),
|
||||
},
|
||||
Spec: &corev1.PodSpecArgs{
|
||||
Containers: corev1.ContainerArray{
|
||||
&corev1.ContainerArgs{
|
||||
Name: pulumi.String("nginx"),
|
||||
Image: pulumi.String("nginx:1.14-alpine"),
|
||||
Resources: &corev1.ResourceRequirementsArgs{
|
||||
Limits: pulumi.StringMap{
|
||||
"memory": pulumi.String("20Mi"),
|
||||
"cpu": pulumi.String("0.2"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
22
pkg/codegen/internal/test/testdata/kubernetes-pod.pp.py
vendored
Normal file
22
pkg/codegen/internal/test/testdata/kubernetes-pod.pp.py
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
import pulumi
|
||||
import pulumi_kubernetes as kubernetes
|
||||
|
||||
bar = kubernetes.core.v1.Pod("bar",
|
||||
api_version="v1",
|
||||
kind="Pod",
|
||||
metadata={
|
||||
"namespace": "foo",
|
||||
"name": "bar",
|
||||
},
|
||||
spec={
|
||||
"containers": [{
|
||||
"name": "nginx",
|
||||
"image": "nginx:1.14-alpine",
|
||||
"resources": {
|
||||
"limits": {
|
||||
"memory": "20Mi",
|
||||
"cpu": "0.2",
|
||||
},
|
||||
},
|
||||
}],
|
||||
})
|
23
pkg/codegen/internal/test/testdata/kubernetes-pod.pp.ts
vendored
Normal file
23
pkg/codegen/internal/test/testdata/kubernetes-pod.pp.ts
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
import * as pulumi from "@pulumi/pulumi";
|
||||
import * as kubernetes from "@pulumi/kubernetes";
|
||||
|
||||
const bar = new kubernetes.core.v1.Pod("bar", {
|
||||
apiVersion: "v1",
|
||||
kind: "Pod",
|
||||
metadata: {
|
||||
namespace: "foo",
|
||||
name: "bar",
|
||||
},
|
||||
spec: {
|
||||
containers: [{
|
||||
name: "nginx",
|
||||
image: "nginx:1.14-alpine",
|
||||
resources: {
|
||||
limits: {
|
||||
memory: "20Mi",
|
||||
cpu: 0.2,
|
||||
},
|
||||
},
|
||||
}],
|
||||
},
|
||||
});
|
22
pkg/codegen/internal/test/testdata/kubernetes-template.pp
vendored
Normal file
22
pkg/codegen/internal/test/testdata/kubernetes-template.pp
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
resource argocd_serverDeployment "kubernetes:apps/v1:Deployment" {
|
||||
apiVersion = "apps/v1"
|
||||
kind = "Deployment"
|
||||
metadata = {
|
||||
name = "argocd-server"
|
||||
}
|
||||
spec = {
|
||||
template = {
|
||||
spec = {
|
||||
containers = [
|
||||
{
|
||||
readinessProbe = {
|
||||
httpGet = {
|
||||
port = 8080
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
41
pkg/codegen/internal/test/testdata/kubernetes-template.pp.cs
vendored
Normal file
41
pkg/codegen/internal/test/testdata/kubernetes-template.pp.cs
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
using Pulumi;
|
||||
using Kubernetes = Pulumi.Kubernetes;
|
||||
|
||||
class MyStack : Stack
|
||||
{
|
||||
public MyStack()
|
||||
{
|
||||
var argocd_serverDeployment = new Kubernetes.Apps.V1.Deployment("argocd_serverDeployment", new Kubernetes.Types.Inputs.Apps.V1.DeploymentArgs
|
||||
{
|
||||
ApiVersion = "apps/v1",
|
||||
Kind = "Deployment",
|
||||
Metadata = new Kubernetes.Types.Inputs.Meta.V1.ObjectMetaArgs
|
||||
{
|
||||
Name = "argocd-server",
|
||||
},
|
||||
Spec = new Kubernetes.Types.Inputs.Apps.V1.DeploymentSpecArgs
|
||||
{
|
||||
Template = new Kubernetes.Types.Inputs.Core.V1.PodTemplateSpecArgs
|
||||
{
|
||||
Spec = new Kubernetes.Types.Inputs.Core.V1.PodSpecArgs
|
||||
{
|
||||
Containers =
|
||||
{
|
||||
new Kubernetes.Types.Inputs.Core.V1.ContainerArgs
|
||||
{
|
||||
ReadinessProbe = new Kubernetes.Types.Inputs.Core.V1.ProbeArgs
|
||||
{
|
||||
HttpGet = new Kubernetes.Types.Inputs.Core.V1.HTTPGetActionArgs
|
||||
{
|
||||
Port = 8080,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
}
|
39
pkg/codegen/internal/test/testdata/kubernetes-template.pp.go
vendored
Normal file
39
pkg/codegen/internal/test/testdata/kubernetes-template.pp.go
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
appsv1 "github.com/pulumi/pulumi-kubernetes/sdk/v2/go/kubernetes/apps/v1"
|
||||
corev1 "github.com/pulumi/pulumi-kubernetes/sdk/v2/go/kubernetes/core/v1"
|
||||
metav1 "github.com/pulumi/pulumi-kubernetes/sdk/v2/go/kubernetes/meta/v1"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/pulumi"
|
||||
)
|
||||
|
||||
func main() {
|
||||
pulumi.Run(func(ctx *pulumi.Context) error {
|
||||
_, err := appsv1.NewDeployment(ctx, "argocd_serverDeployment", &appsv1.DeploymentArgs{
|
||||
ApiVersion: pulumi.String("apps/v1"),
|
||||
Kind: pulumi.String("Deployment"),
|
||||
Metadata: &metav1.ObjectMetaArgs{
|
||||
Name: pulumi.String("argocd-server"),
|
||||
},
|
||||
Spec: &appsv1.DeploymentSpecArgs{
|
||||
Template: &corev1.PodTemplateSpecArgs{
|
||||
Spec: &corev1.PodSpecArgs{
|
||||
Containers: corev1.ContainerArray{
|
||||
&corev1.ContainerArgs{
|
||||
ReadinessProbe: &corev1.ProbeArgs{
|
||||
HttpGet: &corev1.HTTPGetActionArgs{
|
||||
Port: pulumi.Int(8080),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
22
pkg/codegen/internal/test/testdata/kubernetes-template.pp.py
vendored
Normal file
22
pkg/codegen/internal/test/testdata/kubernetes-template.pp.py
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
import pulumi
|
||||
import pulumi_kubernetes as kubernetes
|
||||
|
||||
argocd_server_deployment = kubernetes.apps.v1.Deployment("argocd_serverDeployment",
|
||||
api_version="apps/v1",
|
||||
kind="Deployment",
|
||||
metadata={
|
||||
"name": "argocd-server",
|
||||
},
|
||||
spec={
|
||||
"template": {
|
||||
"spec": {
|
||||
"containers": [{
|
||||
"readiness_probe": {
|
||||
"http_get": {
|
||||
"port": 8080,
|
||||
},
|
||||
},
|
||||
}],
|
||||
},
|
||||
},
|
||||
})
|
23
pkg/codegen/internal/test/testdata/kubernetes-template.pp.ts
vendored
Normal file
23
pkg/codegen/internal/test/testdata/kubernetes-template.pp.ts
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
import * as pulumi from "@pulumi/pulumi";
|
||||
import * as kubernetes from "@pulumi/kubernetes";
|
||||
|
||||
const argocd_serverDeployment = new kubernetes.apps.v1.Deployment("argocd_serverDeployment", {
|
||||
apiVersion: "apps/v1",
|
||||
kind: "Deployment",
|
||||
metadata: {
|
||||
name: "argocd-server",
|
||||
},
|
||||
spec: {
|
||||
template: {
|
||||
spec: {
|
||||
containers: [{
|
||||
readinessProbe: {
|
||||
httpGet: {
|
||||
port: 8080,
|
||||
},
|
||||
},
|
||||
}],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
37768
pkg/codegen/internal/test/testdata/kubernetes.json
vendored
Normal file
37768
pkg/codegen/internal/test/testdata/kubernetes.json
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
@ -119,7 +119,7 @@ func (d DocLanguageHelper) GetModuleDocLink(pkg *schema.Package, modName string)
|
|||
if modName == "" {
|
||||
displayName = fmt.Sprintf("@pulumi/%s", pkg.Name)
|
||||
} else {
|
||||
displayName = fmt.Sprintf("@pulumi/%s/%s", pkg.Name, modName)
|
||||
displayName = fmt.Sprintf("@pulumi/%s/%s", pkg.Name, strings.ToLower(modName))
|
||||
}
|
||||
link = d.GetDocLinkForResourceType(pkg, modName, "")
|
||||
return displayName, link
|
||||
|
|
|
@ -26,7 +26,6 @@ import (
|
|||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -38,9 +37,6 @@ import (
|
|||
"github.com/pulumi/pulumi/sdk/v2/go/common/util/contract"
|
||||
)
|
||||
|
||||
// Match k8s version suffix. Examples include "/v1beta1" and "/v1alpha2".
|
||||
var k8sVersionSuffix = regexp.MustCompile(`/(v\d+((alpha|beta)\d+)?)$`)
|
||||
|
||||
type typeDetails struct {
|
||||
outputType bool
|
||||
inputType bool
|
||||
|
@ -953,13 +949,20 @@ func (mod *modContext) genTypes() (string, string) {
|
|||
mod.genHeader(outputs, mod.sdkImports(true, false), imports)
|
||||
|
||||
// Build a namespace tree out of the types, then emit them.
|
||||
namespaces := mod.getNamespaces()
|
||||
mod.genNamespace(inputs, namespaces[""], true, 0)
|
||||
mod.genNamespace(outputs, namespaces[""], false, 0)
|
||||
|
||||
type namespace struct {
|
||||
name string
|
||||
types []*schema.ObjectType
|
||||
children []*namespace
|
||||
}
|
||||
return inputs.String(), outputs.String()
|
||||
}
|
||||
|
||||
type namespace struct {
|
||||
name string
|
||||
types []*schema.ObjectType
|
||||
children []*namespace
|
||||
}
|
||||
|
||||
func (mod *modContext) getNamespaces() map[string]*namespace {
|
||||
namespaces := map[string]*namespace{}
|
||||
var getNamespace func(string) *namespace
|
||||
getNamespace = func(mod string) *namespace {
|
||||
|
@ -994,38 +997,35 @@ func (mod *modContext) genTypes() (string, string) {
|
|||
ns.types = append(ns.types, t)
|
||||
}
|
||||
|
||||
var genNamespace func(io.Writer, *namespace, bool, int)
|
||||
genNamespace = func(w io.Writer, ns *namespace, input bool, level int) {
|
||||
indent := strings.Repeat(" ", level)
|
||||
return namespaces
|
||||
}
|
||||
|
||||
sort.Slice(ns.types, func(i, j int) bool {
|
||||
return tokenToName(ns.types[i].Token) < tokenToName(ns.types[j].Token)
|
||||
})
|
||||
for i, t := range ns.types {
|
||||
if input && mod.details(t).inputType || !input && mod.details(t).outputType {
|
||||
mod.genType(w, t, input, level)
|
||||
if i != len(ns.types)-1 {
|
||||
fmt.Fprintf(w, "\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
func (mod *modContext) genNamespace(w io.Writer, ns *namespace, input bool, level int) {
|
||||
indent := strings.Repeat(" ", level)
|
||||
|
||||
sort.Slice(ns.children, func(i, j int) bool {
|
||||
return ns.children[i].name < ns.children[j].name
|
||||
})
|
||||
for i, ns := range ns.children {
|
||||
fmt.Fprintf(w, "%sexport namespace %s {\n", indent, ns.name)
|
||||
genNamespace(w, ns, input, level+1)
|
||||
fmt.Fprintf(w, "%s}\n", indent)
|
||||
if i != len(ns.children)-1 {
|
||||
sort.Slice(ns.types, func(i, j int) bool {
|
||||
return tokenToName(ns.types[i].Token) < tokenToName(ns.types[j].Token)
|
||||
})
|
||||
for i, t := range ns.types {
|
||||
if input && mod.details(t).inputType || !input && mod.details(t).outputType {
|
||||
mod.genType(w, t, input, level)
|
||||
if i != len(ns.types)-1 {
|
||||
fmt.Fprintf(w, "\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
genNamespace(inputs, namespaces[""], true, 0)
|
||||
genNamespace(outputs, namespaces[""], false, 0)
|
||||
|
||||
return inputs.String(), outputs.String()
|
||||
sort.Slice(ns.children, func(i, j int) bool {
|
||||
return ns.children[i].name < ns.children[j].name
|
||||
})
|
||||
for i, ns := range ns.children {
|
||||
fmt.Fprintf(w, "%sexport namespace %s {\n", indent, ns.name)
|
||||
mod.genNamespace(w, ns, input, level+1)
|
||||
fmt.Fprintf(w, "%s}\n", indent)
|
||||
if i != len(ns.children)-1 {
|
||||
fmt.Fprintf(w, "\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type fs map[string][]byte
|
||||
|
@ -1170,12 +1170,11 @@ func (mod *modContext) genIndex(exports []string) string {
|
|||
|
||||
for _, mod := range mod.children {
|
||||
child := strings.ToLower(mod.mod)
|
||||
if mod.compatibility == kubernetes20 {
|
||||
// Extract version suffix from child modules. Nested versions will have their own index.ts file.
|
||||
// Example: apps/v1beta1 -> v1beta1
|
||||
if match := k8sVersionSuffix.FindStringSubmatchIndex(child); len(match) != 0 {
|
||||
child = child[match[2]:match[3]]
|
||||
}
|
||||
// Extract version suffix from child modules. Nested versions will have their own index.ts file.
|
||||
// Example: apps/v1beta1 -> v1beta1
|
||||
parts := strings.SplitN(child, "/", 2)
|
||||
if len(parts) == 2 {
|
||||
child = parts[1]
|
||||
}
|
||||
children.Add(child)
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/pulumi/pulumi/pkg/v2/codegen/schema"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/pulumi/pulumi/pkg/v2/codegen"
|
||||
"github.com/pulumi/pulumi/pkg/v2/codegen/hcl2"
|
||||
|
@ -52,6 +54,12 @@ func GenerateProgram(program *hcl2.Program) (map[string][]byte, hcl.Diagnostics,
|
|||
}
|
||||
g.Formatter = format.NewFormatter(g)
|
||||
|
||||
for _, p := range program.Packages() {
|
||||
if err := p.ImportLanguages(map[string]schema.Language{"nodejs": Importer}); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var index bytes.Buffer
|
||||
g.genPreamble(&index, program)
|
||||
for _, n := range nodes {
|
||||
|
@ -215,6 +223,18 @@ func resourceTypeName(r *hcl2.Resource) (string, string, string, hcl.Diagnostics
|
|||
if pkg == "pulumi" && module == "providers" {
|
||||
pkg, module, member = member, "", "Provider"
|
||||
}
|
||||
|
||||
// Normalize module.
|
||||
if r.Schema != nil {
|
||||
pkg := r.Schema.Package
|
||||
if lang, ok := pkg.Language["nodejs"]; ok {
|
||||
pkgInfo := lang.(NodePackageInfo)
|
||||
if m, ok := pkgInfo.ModuleToPackage[module]; ok {
|
||||
module = m
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return makeValidIdentifier(pkg), strings.Replace(module, "/", ".", -1), title(member), diagnostics
|
||||
}
|
||||
|
||||
|
|
|
@ -411,6 +411,8 @@ func (g *generator) GenLiteralValueExpression(w io.Writer, expr *model.LiteralVa
|
|||
switch expr.Type() {
|
||||
case model.BoolType:
|
||||
g.Fgenf(w, "%v", expr.Value.True())
|
||||
case model.NoneType:
|
||||
g.Fgen(w, "undefined")
|
||||
case model.NumberType:
|
||||
bf := expr.Value.AsBigFloat()
|
||||
if i, acc := bf.Int64(); acc == big.Exact {
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
package python
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
|
@ -82,6 +81,34 @@ func (d DocLanguageHelper) GetDocLinkForBuiltInType(typeName string) string {
|
|||
|
||||
// GetLanguageTypeString returns the Python-specific type given a Pulumi schema type.
|
||||
func (d DocLanguageHelper) GetLanguageTypeString(pkg *schema.Package, moduleName string, t schema.Type, input, optional bool) string {
|
||||
// TODO[pulumi/pulumi#5145]: Delete this if check once all providers have UsesIOClasses set to true in their
|
||||
// schema.
|
||||
if pythonPkgInfo, ok := pkg.Language["python"].(PackageInfo); !ok || !pythonPkgInfo.UsesIOClasses {
|
||||
return d.GetLanguageTypeStringLegacy(pkg, moduleName, t, input, optional)
|
||||
}
|
||||
|
||||
typeDetails := map[*schema.ObjectType]*typeDetails{}
|
||||
mod := &modContext{
|
||||
pkg: pkg,
|
||||
mod: moduleName,
|
||||
typeDetails: typeDetails,
|
||||
}
|
||||
typeName := mod.typeString(t, input, false /*wrapInput*/, optional /*optional*/, false /*acceptMapping*/)
|
||||
|
||||
// Remove any package qualifiers from the type name.
|
||||
if !input {
|
||||
typeName = strings.ReplaceAll(typeName, "outputs.", "")
|
||||
}
|
||||
|
||||
// Remove single quote from type names.
|
||||
typeName = strings.ReplaceAll(typeName, "'", "")
|
||||
|
||||
return typeName
|
||||
}
|
||||
|
||||
// TODO[pulumi/pulumi#5145]: Delete this function once all providers have UsesIOClasses set to true in their schema.
|
||||
// GetLanguageTypeStringLegacy returns the legacy type strings.
|
||||
func (d DocLanguageHelper) GetLanguageTypeStringLegacy(pkg *schema.Package, moduleName string, t schema.Type, input, optional bool) string {
|
||||
name := pyType(t)
|
||||
|
||||
// The Python SDK generator will simply return "list" or "dict" for enumerables.
|
||||
|
@ -101,13 +128,13 @@ func (d DocLanguageHelper) GetLanguageTypeString(pkg *schema.Package, moduleName
|
|||
types = append(types, e.String())
|
||||
continue
|
||||
}
|
||||
t := d.GetLanguageTypeString(pkg, moduleName, e, input, optional)
|
||||
t := d.GetLanguageTypeStringLegacy(pkg, moduleName, e, input, optional)
|
||||
types = append(types, t)
|
||||
}
|
||||
return strings.Join(types, " | ")
|
||||
case *schema.MapType:
|
||||
if uTy, ok := dTy.ElementType.(*schema.UnionType); ok {
|
||||
return d.GetLanguageTypeString(pkg, moduleName, uTy, input, optional)
|
||||
return d.GetLanguageTypeStringLegacy(pkg, moduleName, uTy, input, optional)
|
||||
}
|
||||
|
||||
elType := dTy.ElementType.String()
|
||||
|
@ -125,9 +152,10 @@ func (d DocLanguageHelper) GetFunctionName(modName string, f *schema.Function) s
|
|||
return PyName(tokenToName(f.Token))
|
||||
}
|
||||
|
||||
// GetResourceFunctionResultName is not implemented for Python and returns an empty string.
|
||||
// GetResourceFunctionResultName returns the name of the result type when a function is used to lookup
|
||||
// an existing resource.
|
||||
func (d DocLanguageHelper) GetResourceFunctionResultName(modName string, f *schema.Function) string {
|
||||
return ""
|
||||
return title(tokenToName(f.Token)) + "Result"
|
||||
}
|
||||
|
||||
// GenPropertyCaseMap generates the case maps for a property.
|
||||
|
@ -140,10 +168,9 @@ func (d DocLanguageHelper) GenPropertyCaseMap(pkg *schema.Package, modName, tool
|
|||
recordProperty(prop, snakeCaseToCamelCase, camelCaseToSnakeCase, seenTypes)
|
||||
}
|
||||
|
||||
// GetPropertyName is not implemented for Python because property names in Python must use
|
||||
// property case maps, which need to be generated at each provider's package-level.
|
||||
// GetPropertyName returns the property name specific to Python.
|
||||
func (d DocLanguageHelper) GetPropertyName(p *schema.Property) (string, error) {
|
||||
return "", errors.New("this method is not supported for the python language")
|
||||
return PyName(p.Name), nil
|
||||
}
|
||||
|
||||
// elementTypeToName returns the type name from an element type of the form
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -75,6 +75,7 @@ func newGenerator(program *hcl2.Program) (*generator, error) {
|
|||
if err := p.ImportLanguages(map[string]schema.Language{"python": Importer}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
info, _ := p.Language["python"].(PackageInfo)
|
||||
|
||||
// Build the case mapping table.
|
||||
camelCaseToSnakeCase := map[string]string{}
|
||||
|
@ -82,15 +83,17 @@ func newGenerator(program *hcl2.Program) (*generator, error) {
|
|||
buildCaseMappingTables(p, nil, camelCaseToSnakeCase, seenTypes)
|
||||
casingTables[PyName(p.Name)] = camelCaseToSnakeCase
|
||||
|
||||
// Annotate nested types to indicate they are dictionaries.
|
||||
for _, t := range p.Types {
|
||||
if t, ok := t.(*schema.ObjectType); ok {
|
||||
if t.Language == nil {
|
||||
t.Language = map[string]interface{}{}
|
||||
}
|
||||
t.Language["python"] = objectTypeInfo{
|
||||
isDictionary: true,
|
||||
camelCaseToSnakeCase: camelCaseToSnakeCase,
|
||||
// If this package does not use Input/Output classes, annotate nested types to indicate they are dictionaries.
|
||||
if !info.UsesIOClasses {
|
||||
for _, t := range p.Types {
|
||||
if t, ok := t.(*schema.ObjectType); ok {
|
||||
if t.Language == nil {
|
||||
t.Language = map[string]interface{}{}
|
||||
}
|
||||
t.Language["python"] = objectTypeInfo{
|
||||
isDictionary: true,
|
||||
camelCaseToSnakeCase: camelCaseToSnakeCase,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +109,7 @@ func newGenerator(program *hcl2.Program) (*generator, error) {
|
|||
return g, nil
|
||||
}
|
||||
|
||||
// genLeadingTrivia generates the list of leading trivia assicated with a given token.
|
||||
// genLeadingTrivia generates the list of leading trivia associated with a given token.
|
||||
func (g *generator) genLeadingTrivia(w io.Writer, token syntax.Token) {
|
||||
// TODO(pdg): whitespace
|
||||
for _, t := range token.LeadingTrivia {
|
||||
|
@ -116,7 +119,7 @@ func (g *generator) genLeadingTrivia(w io.Writer, token syntax.Token) {
|
|||
}
|
||||
}
|
||||
|
||||
// genTrailingTrivia generates the list of trailing trivia assicated with a given token.
|
||||
// genTrailingTrivia generates the list of trailing trivia associated with a given token.
|
||||
func (g *generator) genTrailingTrivia(w io.Writer, token syntax.Token) {
|
||||
// TODO(pdg): whitespace
|
||||
for _, t := range token.TrailingTrivia {
|
||||
|
@ -126,7 +129,7 @@ func (g *generator) genTrailingTrivia(w io.Writer, token syntax.Token) {
|
|||
}
|
||||
}
|
||||
|
||||
// genTrivia generates the list of trivia assicated with a given token.
|
||||
// genTrivia generates the list of trivia associated with a given token.
|
||||
func (g *generator) genTrivia(w io.Writer, token syntax.Token) {
|
||||
g.genLeadingTrivia(w, token)
|
||||
g.genTrailingTrivia(w, token)
|
||||
|
@ -194,19 +197,77 @@ func (g *generator) genNode(w io.Writer, n hcl2.Node) {
|
|||
}
|
||||
}
|
||||
|
||||
// resourceTypeName computes the python package, module, and type name for the given resource.
|
||||
// resourceTypeName computes the Python package, module, and type name for the given resource.
|
||||
func resourceTypeName(r *hcl2.Resource) (string, string, string, hcl.Diagnostics) {
|
||||
// Compute the resource type from the Pulumi type token.
|
||||
pkg, module, member, diagnostics := r.DecomposeToken()
|
||||
|
||||
components := strings.Split(module, ".")
|
||||
// Normalize module.
|
||||
if r.Schema != nil {
|
||||
pkg := r.Schema.Package
|
||||
if lang, ok := pkg.Language["python"]; ok {
|
||||
pkgInfo := lang.(PackageInfo)
|
||||
if m, ok := pkgInfo.ModuleNameOverrides[module]; ok {
|
||||
module = m
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
components := strings.Split(module, "/")
|
||||
for i, component := range components {
|
||||
components[i] = PyName(component)
|
||||
}
|
||||
|
||||
return PyName(pkg), strings.Join(components, "."), title(member), diagnostics
|
||||
}
|
||||
|
||||
// argumentTypeName computes the Python argument class name for the given expression and model type.
|
||||
func (g *generator) argumentTypeName(expr model.Expression, destType model.Type) string {
|
||||
schemaType, ok := hcl2.GetSchemaForType(destType.(model.Type))
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
objType, ok := schemaType.(*schema.ObjectType)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
if objType.Language != nil {
|
||||
pyTypeInfo, ok := objType.Language["python"].(objectTypeInfo)
|
||||
if ok {
|
||||
if pyTypeInfo.isDictionary {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
token := objType.Token
|
||||
tokenRange := expr.SyntaxNode().Range()
|
||||
|
||||
// Example: aws, s3/BucketLogging, BucketLogging, []Diagnostics
|
||||
pkgName, module, member, diagnostics := hcl2.DecomposeToken(token, tokenRange)
|
||||
contract.Assert(len(diagnostics) == 0)
|
||||
|
||||
modName := objType.Package.TokenToModule(token)
|
||||
|
||||
// Normalize module.
|
||||
pkg := objType.Package
|
||||
if lang, ok := pkg.Language["python"]; ok {
|
||||
pkgInfo := lang.(PackageInfo)
|
||||
if m, ok := pkgInfo.ModuleNameOverrides[module]; ok {
|
||||
modName = m
|
||||
}
|
||||
}
|
||||
if modName != "" {
|
||||
modName = "." + PyName(modName)
|
||||
}
|
||||
modName = strings.Replace(modName, "_", ".", -1)
|
||||
member = member + "Args"
|
||||
|
||||
// Example: aws.s3.BucketLoggingArgs
|
||||
return fmt.Sprintf("%s%s.%s", PyName(pkgName), modName, title(member))
|
||||
}
|
||||
|
||||
// makeResourceName returns the expression that should be emitted for a resource's "name" parameter given its base name
|
||||
// and the count variable name, if any.
|
||||
func (g *generator) makeResourceName(baseName, count string) string {
|
||||
|
@ -231,7 +292,7 @@ func (g *generator) lowerResourceOptions(opts *hcl2.ResourceOptions) (*model.Blo
|
|||
}
|
||||
}
|
||||
|
||||
value, valueTemps := g.lowerExpression(value)
|
||||
value, valueTemps := g.lowerExpression(value, value.Type())
|
||||
temps = append(temps, valueTemps...)
|
||||
|
||||
block.Body.Items = append(block.Body.Items, &model.Attribute{
|
||||
|
@ -302,12 +363,14 @@ func (g *generator) genResource(w io.Writer, r *hcl2.Resource) {
|
|||
g.genTrivia(w, r.Definition.Tokens.GetOpenBrace())
|
||||
|
||||
casingTable := g.casingTables[pkg]
|
||||
for _, attr := range r.Inputs {
|
||||
g.lowerObjectKeys(attr.Value, casingTable)
|
||||
for _, input := range r.Inputs {
|
||||
g.lowerObjectKeys(input.Value, casingTable)
|
||||
|
||||
value, valueTemps := g.lowerExpression(attr.Value)
|
||||
destType, diagnostics := r.InputType.Traverse(hcl.TraverseAttr{Name: input.Name})
|
||||
g.diagnostics = append(g.diagnostics, diagnostics...)
|
||||
value, valueTemps := g.lowerExpression(input.Value, destType.(model.Type))
|
||||
temps = append(temps, valueTemps...)
|
||||
attr.Value = value
|
||||
input.Value = value
|
||||
}
|
||||
g.genTemps(w, temps)
|
||||
|
||||
|
@ -403,7 +466,7 @@ func (g *generator) genConfigVariable(w io.Writer, v *hcl2.ConfigVariable) {
|
|||
var defaultValue model.Expression
|
||||
var temps []*quoteTemp
|
||||
if v.DefaultValue != nil {
|
||||
defaultValue, temps = g.lowerExpression(v.DefaultValue)
|
||||
defaultValue, temps = g.lowerExpression(v.DefaultValue, v.DefaultValue.Type())
|
||||
}
|
||||
g.genTemps(w, temps)
|
||||
|
||||
|
@ -418,7 +481,7 @@ func (g *generator) genConfigVariable(w io.Writer, v *hcl2.ConfigVariable) {
|
|||
}
|
||||
|
||||
func (g *generator) genLocalVariable(w io.Writer, v *hcl2.LocalVariable) {
|
||||
value, temps := g.lowerExpression(v.Definition.Value)
|
||||
value, temps := g.lowerExpression(v.Definition.Value, v.Type())
|
||||
g.genTemps(w, temps)
|
||||
|
||||
// TODO(pdg): trivia
|
||||
|
@ -426,7 +489,7 @@ func (g *generator) genLocalVariable(w io.Writer, v *hcl2.LocalVariable) {
|
|||
}
|
||||
|
||||
func (g *generator) genOutputVariable(w io.Writer, v *hcl2.OutputVariable) {
|
||||
value, temps := g.lowerExpression(v.Value)
|
||||
value, temps := g.lowerExpression(v.Value, v.Type())
|
||||
g.genTemps(w, temps)
|
||||
|
||||
// TODO(pdg): trivia
|
||||
|
|
|
@ -23,13 +23,15 @@ func (nameInfo) Format(name string) string {
|
|||
return PyName(name)
|
||||
}
|
||||
|
||||
func (g *generator) lowerExpression(expr model.Expression) (model.Expression, []*quoteTemp) {
|
||||
func (g *generator) lowerExpression(expr model.Expression, typ model.Type) (model.Expression, []*quoteTemp) {
|
||||
// TODO(pdg): diagnostics
|
||||
|
||||
expr = hcl2.RewritePropertyReferences(expr)
|
||||
expr, _ = hcl2.RewriteApplies(expr, nameInfo(0), false)
|
||||
expr, _ = g.lowerProxyApplies(expr)
|
||||
expr = hcl2.RewriteConversions(expr, typ)
|
||||
expr, quotes, _ := g.rewriteQuotes(expr)
|
||||
|
||||
return expr, quotes
|
||||
}
|
||||
|
||||
|
@ -169,7 +171,7 @@ func (g *generator) genApply(w io.Writer, expr *model.FunctionCallExpression) {
|
|||
}
|
||||
}
|
||||
|
||||
// functionName computes the NodeJS package, module, and name for the given function token.
|
||||
// functionName computes the Python package, module, and name for the given function token.
|
||||
func functionName(tokenArg model.Expression) (string, string, string, hcl.Diagnostics) {
|
||||
token := tokenArg.(*model.TemplateExpression).Parts[0].(*model.LiteralValueExpression).Value.AsString()
|
||||
tokenRange := tokenArg.SyntaxNode().Range()
|
||||
|
@ -198,6 +200,13 @@ func (g *generator) getFunctionImports(x *model.FunctionCallExpression) string {
|
|||
|
||||
func (g *generator) GenFunctionCallExpression(w io.Writer, expr *model.FunctionCallExpression) {
|
||||
switch expr.Name {
|
||||
case hcl2.IntrinsicConvert:
|
||||
switch arg := expr.Args[0].(type) {
|
||||
case *model.ObjectConsExpression:
|
||||
g.genObjectConsExpression(w, arg, expr.Type())
|
||||
default:
|
||||
g.Fgenf(w, "%.v", expr.Args[0])
|
||||
}
|
||||
case hcl2.IntrinsicApply:
|
||||
g.genApply(w, expr)
|
||||
case "element":
|
||||
|
@ -226,29 +235,31 @@ func (g *generator) GenFunctionCallExpression(w io.Writer, expr *model.FunctionC
|
|||
g.Fgenf(w, "%s(", name)
|
||||
|
||||
casingTable := g.casingTables[pkg]
|
||||
if obj, ok := expr.Args[1].(*model.ObjectConsExpression); ok {
|
||||
g.lowerObjectKeys(expr.Args[1], casingTable)
|
||||
if obj, ok := expr.Args[1].(*model.FunctionCallExpression); ok {
|
||||
if obj, ok := obj.Args[0].(*model.ObjectConsExpression); ok {
|
||||
g.lowerObjectKeys(expr.Args[1], casingTable)
|
||||
|
||||
indenter := func(f func()) { f() }
|
||||
if len(obj.Items) > 1 {
|
||||
indenter = g.Indented
|
||||
}
|
||||
indenter(func() {
|
||||
for i, item := range obj.Items {
|
||||
// Ignore non-literal keys
|
||||
key, ok := item.Key.(*model.LiteralValueExpression)
|
||||
if !ok || !key.Value.Type().Equals(cty.String) {
|
||||
continue
|
||||
}
|
||||
|
||||
keyVal := PyName(key.Value.AsString())
|
||||
if i == 0 {
|
||||
g.Fgenf(w, "%s=%.v", keyVal, item.Value)
|
||||
} else {
|
||||
g.Fgenf(w, ",\n%s%s=%.v", g.Indent, keyVal, item.Value)
|
||||
}
|
||||
indenter := func(f func()) { f() }
|
||||
if len(obj.Items) > 1 {
|
||||
indenter = g.Indented
|
||||
}
|
||||
})
|
||||
indenter(func() {
|
||||
for i, item := range obj.Items {
|
||||
// Ignore non-literal keys
|
||||
key, ok := item.Key.(*model.LiteralValueExpression)
|
||||
if !ok || !key.Value.Type().Equals(cty.String) {
|
||||
continue
|
||||
}
|
||||
|
||||
keyVal := PyName(key.Value.AsString())
|
||||
if i == 0 {
|
||||
g.Fgenf(w, "%s=%.v", keyVal, item.Value)
|
||||
} else {
|
||||
g.Fgenf(w, ",\n%s%s=%.v", g.Indent, keyVal, item.Value)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
g.Fgenf(w, "%v)", optionsBag)
|
||||
|
@ -338,6 +349,8 @@ func (g *generator) GenLiteralValueExpression(w io.Writer, expr *model.LiteralVa
|
|||
} else {
|
||||
g.Fgen(w, "False")
|
||||
}
|
||||
case model.NoneType:
|
||||
g.Fgen(w, "None")
|
||||
case model.NumberType:
|
||||
bf := expr.Value.AsBigFloat()
|
||||
if i, acc := bf.Int64(); acc == big.Exact {
|
||||
|
@ -356,16 +369,40 @@ func (g *generator) GenLiteralValueExpression(w io.Writer, expr *model.LiteralVa
|
|||
}
|
||||
|
||||
func (g *generator) GenObjectConsExpression(w io.Writer, expr *model.ObjectConsExpression) {
|
||||
if len(expr.Items) == 0 {
|
||||
g.Fgen(w, "{}")
|
||||
g.genObjectConsExpression(w, expr, expr.Type())
|
||||
}
|
||||
|
||||
func (g *generator) genObjectConsExpression(w io.Writer, expr *model.ObjectConsExpression, destType model.Type) {
|
||||
typeName := g.argumentTypeName(expr, destType) // Example: aws.s3.BucketLoggingArgs
|
||||
if typeName != "" {
|
||||
// If a typeName exists, treat this as an Input Class e.g. aws.s3.BucketLoggingArgs(key="value", foo="bar", ...)
|
||||
if len(expr.Items) == 0 {
|
||||
g.Fgenf(w, "%s()", typeName)
|
||||
} else {
|
||||
g.Fgenf(w, "%s(\n", typeName)
|
||||
g.Indented(func() {
|
||||
for _, item := range expr.Items {
|
||||
g.Fgenf(w, "%s", g.Indent)
|
||||
lit := item.Key.(*model.LiteralValueExpression)
|
||||
g.Fprint(w, PyName(lit.Value.AsString()))
|
||||
g.Fgenf(w, "=%.v,\n", item.Value)
|
||||
}
|
||||
})
|
||||
g.Fgenf(w, "%s)", g.Indent)
|
||||
}
|
||||
} else {
|
||||
g.Fgen(w, "{")
|
||||
g.Indented(func() {
|
||||
for _, item := range expr.Items {
|
||||
g.Fgenf(w, "\n%s%.v: %.v,", g.Indent, item.Key, item.Value)
|
||||
}
|
||||
})
|
||||
g.Fgenf(w, "\n%s}", g.Indent)
|
||||
// Otherwise treat this as an untyped dictionary e.g. {"key": "value", "foo": "bar", ...}
|
||||
if len(expr.Items) == 0 {
|
||||
g.Fgen(w, "{}")
|
||||
} else {
|
||||
g.Fgen(w, "{")
|
||||
g.Indented(func() {
|
||||
for _, item := range expr.Items {
|
||||
g.Fgenf(w, "\n%s%.v: %.v,", g.Indent, item.Key, item.Value)
|
||||
}
|
||||
})
|
||||
g.Fgenf(w, "\n%s}", g.Indent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ resource rta "aws:ec2:RouteTableAssociation" {
|
|||
prop, ok := rta.Definition.Body.Attribute("subnetId")
|
||||
assert.True(t, ok)
|
||||
|
||||
x, temps := g.lowerExpression(prop.Value)
|
||||
x, temps := g.lowerExpression(prop.Value, prop.Type())
|
||||
assert.Len(t, temps, 0)
|
||||
|
||||
x.SetLeadingTrivia(nil)
|
||||
|
|
|
@ -40,6 +40,8 @@ type PackageInfo struct {
|
|||
ModuleNameOverrides map[string]string `json:"moduleNameOverrides,omitempty"`
|
||||
// Toggle compatibility mode for a specified target.
|
||||
Compatibility string `json:"compatibility,omitempty"`
|
||||
// Indicates whether the package generates input/output classes.
|
||||
UsesIOClasses bool `json:"usesIOClasses,omitempty"`
|
||||
}
|
||||
|
||||
// Importer implements schema.Language for Python.
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
package python
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
@ -22,8 +23,77 @@ import (
|
|||
"github.com/pulumi/pulumi/pkg/v2/codegen"
|
||||
)
|
||||
|
||||
// useLegacyName are names that should return the result of PyNameLegacy from PyName, for compatibility.
|
||||
var useLegacyName = codegen.StringSet{
|
||||
// The following property name of a nested type is a case where the newer algorithm produces an incorrect name
|
||||
// (`open_xjson_ser_de`). It should be the legacy name of `open_x_json_ser_de`.
|
||||
// TODO[pulumi/pulumi#5199]: We should see if we can fix this in the algorithm of PyName so it doesn't need to
|
||||
// be special-cased in this set.
|
||||
"openXJsonSerDe": struct{}{}, // AWS
|
||||
|
||||
// The following function name has already shipped with the legacy name (`get_public_i_ps`).
|
||||
// TODO[pulumi/pulumi#5200]: Consider emitting two functions: one with the correct name (`get_public_ips`)
|
||||
// and another function with the legacy name (`get_public_i_ps`) marked as deprecated.
|
||||
"GetPublicIPs": struct{}{}, // Azure
|
||||
|
||||
// The following function name has already shipped with the legacy name (`get_uptime_check_i_ps`).
|
||||
// TODO[pulumi/pulumi#5200]: Consider emitting two functions: one with the correct name (`get_uptime_check_ips`)
|
||||
// and another function with the legacy name (`get_uptime_check_i_ps`) marked as deprecated.
|
||||
"GetUptimeCheckIPs": struct{}{}, // GCP
|
||||
}
|
||||
|
||||
// excludeFromPanic are names that are ok to have different results from PyName and PyNameLegacy.
|
||||
var excludeFromPanic = codegen.StringSet{
|
||||
// The following all show up as properties of nested input/output classes only, so it's OK that the current
|
||||
// and legacy names are different since we haven't previously generated any input/output classes (hence no
|
||||
// breaking change).
|
||||
"nonResourceURLs": struct{}{}, // K8s
|
||||
"targetWWNs": struct{}{}, // K8s
|
||||
"podCIDRs": struct{}{}, // K8s
|
||||
"podIPs": struct{}{}, // K8s
|
||||
"externalIPs": struct{}{}, // K8s
|
||||
"publicIPs": struct{}{}, // Azure
|
||||
"effectiveOutboundIPs": struct{}{}, // Azure
|
||||
"doNotRunExtensionsOnOverprovisionedVMs": struct{}{}, // Azure
|
||||
"vCPUs": struct{}{}, // Azure
|
||||
"networkACLs": struct{}{}, // Azure
|
||||
"allocatableVMs": struct{}{}, // Azure
|
||||
"publicIPsToAllow": struct{}{}, // Azure
|
||||
"managedOutboundIPs": struct{}{}, // Azure
|
||||
"outboundIPs": struct{}{}, // Azure
|
||||
"staticIPs": struct{}{}, // Azure
|
||||
"sendMDNAsynchronously": struct{}{}, // Azure
|
||||
"adminGroupObjectIDs": struct{}{}, // Azure
|
||||
"GuestConfigurationHCRPAssignment": struct{}{}, // Azure
|
||||
"GetGuestConfigurationHCRPAssignment": struct{}{}, // Azure
|
||||
"clusterUsersGroupDNs": struct{}{}, // Azure
|
||||
}
|
||||
|
||||
// PyName turns a variable or function name, normally using camelCase, to an underscore_case name.
|
||||
// It panics if the result is different from PyNameLegacy, unless name is in excludeFromPanic, to help catch
|
||||
// unintended breaking changes.
|
||||
// TODO[pulumi/pulumi#5201]: Once all providers have been updated to use this version of the codegen (or later),
|
||||
// we can go back and remove the panic.
|
||||
func PyName(name string) string {
|
||||
current := pyName(name, useLegacyName.Has(name))
|
||||
if excludeFromPanic.Has(name) {
|
||||
return current
|
||||
}
|
||||
legacy := PyNameLegacy(name)
|
||||
if current != legacy {
|
||||
panic(fmt.Sprintf("PyName(%[1]q) != PyNameLegacy(%[1]q) (%q != %q)", name, current, legacy))
|
||||
}
|
||||
return current
|
||||
}
|
||||
|
||||
// Deprecated: Use PyName instead.
|
||||
// PyNameLegacy is an uncorrected and deprecated version of the PyName algorithm to maintain compatibility and avoid
|
||||
// a breaking change. See the linked issue for more context: https://github.com/pulumi/pulumi-kubernetes/issues/1179
|
||||
func PyNameLegacy(name string) string {
|
||||
return pyName(name, true /*legacy*/)
|
||||
}
|
||||
|
||||
func pyName(name string, legacy bool) string {
|
||||
// This method is a state machine with four states:
|
||||
// stateFirst - the initial state.
|
||||
// stateUpper - The last character we saw was an uppercase letter and the character before it
|
||||
|
@ -119,9 +189,9 @@ func PyName(name string) string {
|
|||
continue
|
||||
}
|
||||
|
||||
// We want to fold digits immediately following an acronym into the same
|
||||
// component as the acronym.
|
||||
if unicode.IsDigit(char) {
|
||||
// We want to fold digits (or the lowercase letter 's' if not the legacy algo) immediately following
|
||||
// an acronym into the same component as the acronym.
|
||||
if unicode.IsDigit(char) || (char == 's' && !legacy) {
|
||||
// stateAcronym -> stateLowerOrNumber
|
||||
state = stateLowerOrNumber
|
||||
currentComponent.WriteRune(char)
|
||||
|
|
55
pkg/codegen/python/python_test.go
Normal file
55
pkg/codegen/python/python_test.go
Normal file
|
@ -0,0 +1,55 @@
|
|||
package python
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var pyNameTests = []struct {
|
||||
input string
|
||||
expected string
|
||||
legacy string
|
||||
}{
|
||||
{"kubeletConfigKey", "kubelet_config_key", "kubelet_config_key"},
|
||||
{"podCIDR", "pod_cidr", "pod_cidr"},
|
||||
{"podCidr", "pod_cidr", "pod_cidr"},
|
||||
{"podCIDRs", "pod_cidrs", "pod_cid_rs"},
|
||||
{"podIPs", "pod_ips", "pod_i_ps"},
|
||||
{"nonResourceURLs", "non_resource_urls", "non_resource_ur_ls"},
|
||||
{"someTHINGsAREWeird", "some_things_are_weird", "some_thin_gs_are_weird"},
|
||||
{"podCIDRSet", "pod_cidr_set", "pod_cidr_set"},
|
||||
{"Sha256Hash", "sha256_hash", "sha256_hash"},
|
||||
{"SHA256Hash", "sha256_hash", "sha256_hash"},
|
||||
|
||||
// PyName should return the legacy name for these:
|
||||
{"openXJsonSerDe", "open_x_json_ser_de", "open_x_json_ser_de"},
|
||||
{"GetPublicIPs", "get_public_i_ps", "get_public_i_ps"},
|
||||
{"GetUptimeCheckIPs", "get_uptime_check_i_ps", "get_uptime_check_i_ps"},
|
||||
}
|
||||
|
||||
func TestPyName(t *testing.T) {
|
||||
for _, tt := range pyNameTests {
|
||||
t.Run(tt.input, func(t *testing.T) {
|
||||
// TODO[pulumi/pulumi#5201]: Once the assertion has been removed, we can remove this `if` block.
|
||||
// Prevent this input from panic'ing.
|
||||
if tt.input == "someTHINGsAREWeird" {
|
||||
result := pyName(tt.input, false /*legacy*/)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
return
|
||||
}
|
||||
|
||||
result := PyName(tt.input)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPyNameLegacy(t *testing.T) {
|
||||
for _, tt := range pyNameTests {
|
||||
t.Run(tt.input, func(t *testing.T) {
|
||||
result := PyNameLegacy(tt.input)
|
||||
assert.Equal(t, tt.legacy, result)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -156,6 +156,8 @@ func (*UnionType) isType() {}
|
|||
|
||||
// ObjectType represents schematized maps from strings to particular types.
|
||||
type ObjectType struct {
|
||||
// Package is the package that defines the resource.
|
||||
Package *Package
|
||||
// Token is the type's Pulumi type token.
|
||||
Token string
|
||||
// Comment is the description of the type, if any.
|
||||
|
@ -245,6 +247,8 @@ type Alias struct {
|
|||
|
||||
// Resource describes a Pulumi resource.
|
||||
type Resource struct {
|
||||
// Package is the package that defines the resource.
|
||||
Package *Package
|
||||
// Token is the resource's Pulumi type token.
|
||||
Token string
|
||||
// Comment is the description of the resource, if any.
|
||||
|
@ -267,6 +271,8 @@ type Resource struct {
|
|||
|
||||
// Function describes a Pulumi function.
|
||||
type Function struct {
|
||||
// Package is the package that defines the function.
|
||||
Package *Package
|
||||
// Token is the function's Pulumi type token.
|
||||
Token string
|
||||
// Comment is the description of the function, if any.
|
||||
|
@ -738,7 +744,9 @@ func ImportSpec(spec PackageSpec, languages map[string]Language) (*Package, erro
|
|||
return nil, errors.Wrap(err, "compiling module format regexp")
|
||||
}
|
||||
|
||||
types, err := bindTypes(spec.Types)
|
||||
pkg := &Package{}
|
||||
|
||||
types, err := bindTypes(pkg, spec.Types)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "binding types")
|
||||
}
|
||||
|
@ -790,7 +798,7 @@ func ImportSpec(spec PackageSpec, languages map[string]Language) (*Package, erro
|
|||
language[name] = raw
|
||||
}
|
||||
|
||||
pkg := &Package{
|
||||
*pkg = Package{
|
||||
moduleFormat: moduleFormatRegexp,
|
||||
Name: spec.Name,
|
||||
Version: version,
|
||||
|
@ -817,6 +825,8 @@ func ImportSpec(spec PackageSpec, languages map[string]Language) (*Package, erro
|
|||
}
|
||||
|
||||
type types struct {
|
||||
pkg *Package
|
||||
|
||||
objects map[string]*ObjectType
|
||||
arrays map[Type]*ArrayType
|
||||
maps map[Type]*MapType
|
||||
|
@ -1102,6 +1112,7 @@ func (t *types) bindObjectTypeDetails(obj *ObjectType, token string, spec Object
|
|||
language[name] = raw
|
||||
}
|
||||
|
||||
obj.Package = t.pkg
|
||||
obj.Token = token
|
||||
obj.Comment = spec.Description
|
||||
obj.Language = language
|
||||
|
@ -1118,8 +1129,9 @@ func (t *types) bindObjectType(token string, spec ObjectTypeSpec) (*ObjectType,
|
|||
return obj, nil
|
||||
}
|
||||
|
||||
func bindTypes(objects map[string]ObjectTypeSpec) (*types, error) {
|
||||
func bindTypes(pkg *Package, objects map[string]ObjectTypeSpec) (*types, error) {
|
||||
typs := &types{
|
||||
pkg: pkg,
|
||||
objects: map[string]*ObjectType{},
|
||||
arrays: map[Type]*ArrayType{},
|
||||
maps: map[Type]*MapType{},
|
||||
|
@ -1186,6 +1198,7 @@ func bindResource(token string, spec ResourceSpec, types *types) (*Resource, err
|
|||
}
|
||||
|
||||
return &Resource{
|
||||
Package: types.pkg,
|
||||
Token: token,
|
||||
Comment: spec.Description,
|
||||
InputProperties: inputProperties,
|
||||
|
@ -1250,6 +1263,7 @@ func bindFunction(token string, spec FunctionSpec, types *types) (*Function, err
|
|||
}
|
||||
|
||||
return &Function{
|
||||
Package: types.pkg,
|
||||
Token: token,
|
||||
Comment: spec.Description,
|
||||
Inputs: inputs,
|
||||
|
|
46
pkg/codegen/schema/schema_test.go
Normal file
46
pkg/codegen/schema/schema_test.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
// Copyright 2016-2020, 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.
|
||||
|
||||
package schema
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestImportSpec(t *testing.T) {
|
||||
// Read in, decode, and import the schema.
|
||||
schemaBytes, err := ioutil.ReadFile(filepath.Join("..", "internal", "test", "testdata", "kubernetes.json"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var pkgSpec PackageSpec
|
||||
if err = json.Unmarshal(schemaBytes, &pkgSpec); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pkg, err := ImportSpec(pkgSpec, nil)
|
||||
if err != nil {
|
||||
t.Errorf("ImportSpec() error = %v", err)
|
||||
}
|
||||
|
||||
for _, r := range pkg.Resources {
|
||||
assert.NotNil(t, r.Package, "expected resource %s to have an associated Package", r.Token)
|
||||
}
|
||||
}
|
22
pkg/go.mod
22
pkg/go.mod
|
@ -10,21 +10,18 @@ replace (
|
|||
|
||||
require (
|
||||
cloud.google.com/go/logging v1.0.0
|
||||
cloud.google.com/go/storage v1.6.0
|
||||
cloud.google.com/go/storage v1.9.0
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
||||
github.com/Azure/go-autorest/autorest v0.10.0 // indirect
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2 // indirect
|
||||
github.com/Azure/go-autorest/autorest/to v0.3.0 // indirect
|
||||
github.com/Azure/go-autorest/autorest/validation v0.2.0 // indirect
|
||||
github.com/Sirupsen/logrus v1.0.5 // indirect
|
||||
github.com/aws/aws-sdk-go v1.30.7
|
||||
github.com/aws/aws-sdk-go v1.31.13
|
||||
github.com/blang/semver v3.5.1+incompatible
|
||||
github.com/djherbis/times v1.2.0
|
||||
github.com/docker/docker v0.0.0-20170504205632-89658bed64c2
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
||||
github.com/golang/protobuf v1.3.5
|
||||
github.com/golang/protobuf v1.4.2
|
||||
github.com/google/go-querystring v1.0.0
|
||||
github.com/gorilla/mux v1.7.4
|
||||
github.com/hashicorp/go-multierror v1.0.0
|
||||
|
@ -46,17 +43,18 @@ require (
|
|||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
|
||||
github.com/spf13/cobra v1.0.0
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7
|
||||
github.com/xeipuuv/gojsonschema v1.2.0
|
||||
github.com/zclconf/go-cty v1.3.1
|
||||
gocloud.dev v0.19.1-0.20200517170643-46480dc2c3dd
|
||||
gocloud.dev/secrets/hashivault v0.19.1-0.20200517170643-46480dc2c3dd
|
||||
gocloud.dev v0.20.0
|
||||
gocloud.dev/secrets/hashivault v0.20.0
|
||||
golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a
|
||||
google.golang.org/api v0.20.0
|
||||
google.golang.org/genproto v0.0.0-20200318110522-7735f76e9fa5
|
||||
google.golang.org/grpc v1.28.0
|
||||
google.golang.org/api v0.26.0
|
||||
google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482
|
||||
google.golang.org/grpc v1.29.1
|
||||
gopkg.in/AlecAivazis/survey.v1 v1.8.9-0.20200217094205-6773bdf39b7f
|
||||
gopkg.in/src-d/go-git.v4 v4.13.1
|
||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0
|
||||
|
|
178
pkg/go.sum
178
pkg/go.sum
|
@ -13,43 +13,59 @@ cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6T
|
|||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0 h1:MZQCQQaRwOrAcuKjiHWHrgKykt4fZyuwF2dtiG3fGW8=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.55.0/go.mod h1:ZHmoY+/lIMNkN2+fBmuTiqZ4inFhvQad8ft7MT8IV5Y=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.58.0 h1:vtAfVc723K3xKq1BQydk/FyCldnaNFhGhpJxaJzgRMQ=
|
||||
cloud.google.com/go v0.58.0/go.mod h1:W+9FnSUw6nhVwXlFcp1eL+krq5+HQUJeUogSeJZZiWg=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0 h1:xE3CPsOgttP4ACBePh79zTKALtXwn/Edhcr16R5hMWU=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0 h1:PQcPefKFdaIzjQFbiyOgAqyx8q5djaE7x9Sqe712DPA=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/firestore v1.2.0/go.mod h1:iISCjWnTpnoJT1R287xRdjvQHJrxQOpeah4phb5D3h0=
|
||||
cloud.google.com/go/logging v1.0.0 h1:kaunpnoEh9L4hu6JUsBa8Y20LBfKnCuDhKUgdZp7oK8=
|
||||
cloud.google.com/go/logging v1.0.0/go.mod h1:V1cc3ogwobYzQq5f2R7DS/GvRIrI4FKj01Gs5glwAls=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0 h1:Lpy6hKgdcl7a3WGSfJIFmxmcdjSpP6OmBEfcOv1Y680=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1 h1:ukjixP1wl0LpnZ6LWtZJ0mX5tBmjp1f8Sqer8Z2OMUU=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0 h1:UDpwYIwla4jHGzZJaEJYx1tOejbgSoNqsAfHAUYe2r8=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.9.0 h1:oXnZyBjHB6hC8TnSle0AWW6pGJ29EuSo5ww+SFmdNBg=
|
||||
cloud.google.com/go/storage v1.9.0/go.mod h1:m+/etGaqZbylxaNT876QGXqEHp4PR2Rq5GMqICWb9bU=
|
||||
contrib.go.opencensus.io/exporter/aws v0.0.0-20181029163544-2befc13012d0/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA=
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.5.0/go.mod h1:ImxhfLRpxoYiSq891pBrLVhN+qmP8BTVvdH2YLs7Gl0=
|
||||
contrib.go.opencensus.io/exporter/stackdriver v0.12.1/go.mod h1:iwB6wGarfphGGe/e5CWqyUk/cLzKnWsOKPVW3no6OTw=
|
||||
contrib.go.opencensus.io/integrations/ocsql v0.1.4/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE=
|
||||
contrib.go.opencensus.io/resource v0.1.1/go.mod h1:F361eGI91LCmW1I/Saf+rX0+OFcigGlFvXwEGEnkRLA=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/AlecAivazis/survey/v2 v2.0.5/go.mod h1:WYBhg6f0y/fNYUuesWQc0PKbJcEliGcYHB9sNT3Bg74=
|
||||
github.com/Azure/azure-amqp-common-go/v2 v2.1.0/go.mod h1:R8rea+gJRuJR6QxTir/XuEd+YuKoUiazDC/N96FiDEU=
|
||||
github.com/Azure/azure-amqp-common-go/v3 v3.0.0/go.mod h1:SY08giD/XbhTz07tJdpw1SoxQXHPN30+DI3Z04SYqyg=
|
||||
github.com/Azure/azure-pipeline-go v0.2.1 h1:OLBdZJ3yvOn2MezlWvbrBMTEUQC72zAftRZOMdj5HYo=
|
||||
github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
|
||||
github.com/Azure/azure-sdk-for-go v29.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v30.1.0+incompatible h1:HyYPft8wXpxMd0kfLtXo6etWcO+XuPbLkcgx9g2cqxU=
|
||||
github.com/Azure/azure-sdk-for-go v30.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-service-bus-go v0.9.1/go.mod h1:yzBx6/BUGfjfeqbRZny9AQIbIe3AcV9WZbAdpkoXOa0=
|
||||
github.com/Azure/azure-storage-blob-go v0.8.0 h1:53qhf0Oxa0nOjgbDeeYPUeyiNmafAFEY95rZLK0Tj6o=
|
||||
github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0=
|
||||
github.com/Azure/azure-pipeline-go v0.2.2 h1:6oiIS9yaG6XCCzhgAgKFfIWyo4LLCiDhZot6ltoThhY=
|
||||
github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc=
|
||||
github.com/Azure/azure-sdk-for-go v37.1.0+incompatible h1:aFlw3lP7ZHQi4m1kWCpcwYtczhDkGhDoRaMTaxcOf68=
|
||||
github.com/Azure/azure-sdk-for-go v37.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-service-bus-go v0.10.1/go.mod h1:E/FOceuKAFUfpbIJDKWz/May6guE+eGibfGT6q+n1to=
|
||||
github.com/Azure/azure-storage-blob-go v0.9.0 h1:kORqvzXP8ORhKbW13FflGUaSE5CMyDWun9UwMxY8gPs=
|
||||
github.com/Azure/azure-storage-blob-go v0.9.0/go.mod h1:8UBPbiOhrMQ4pLPi3gA1tXnpjrS76UYE/fo5A40vf4g=
|
||||
github.com/Azure/go-amqp v0.12.6/go.mod h1:qApuH6OFTSKZFmCOxccvAv5rLizBQf4v8pRmG138DPo=
|
||||
github.com/Azure/go-amqp v0.12.7/go.mod h1:qApuH6OFTSKZFmCOxccvAv5rLizBQf4v8pRmG138DPo=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-autorest v12.4.3+incompatible h1:tCkdkgLZqAk+43nZu3wda9n413Q2g+z7xp1wmjiJTPY=
|
||||
github.com/Azure/go-autorest v12.4.3+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
||||
github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0=
|
||||
github.com/Azure/go-autorest/autorest v0.10.0 h1:mvdtztBqcL8se7MdrUweNieTNi4kfNG6GOJuurQJpuY=
|
||||
|
@ -59,6 +75,8 @@ github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S
|
|||
github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.2 h1:O1X4oexUxnZCaEUGsvMnr8ZGj8HI37tNezwY4npRqA0=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.3 h1:O1AGG9Xig71FxdX9HO5pGNyZ7TbSyHaVg+5eJO/jSGw=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.3/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2 h1:iM6UAvjR97ZIeR93qTcwpKNMpV+/FTWjwEbuPD495Tk=
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM=
|
||||
github.com/Azure/go-autorest/autorest/azure/cli v0.3.1 h1:LXl088ZQlP0SBppGFsRZonW6hSvwgL5gRByMbvUbx8U=
|
||||
|
@ -104,12 +122,10 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd
|
|||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
|
||||
github.com/aws/aws-sdk-go v1.19.18/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.19.45/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.30.7 h1:IaXfqtioP6p9SFAnNfsqdNczbR5UNbYqvcZUSsCAdTY=
|
||||
github.com/aws/aws-sdk-go v1.30.7/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
github.com/aws/aws-sdk-go v1.31.13 h1:UeWMTRTL0XAKLR7vxDL4/u7KOtz/LtfJr+lXtxN4YEQ=
|
||||
github.com/aws/aws-sdk-go v1.31.13/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
|
@ -132,7 +148,6 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
|
|||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7 h1:6pwm8kMQKCmgUg0ZHTm5+/YvRK0s3THD/28+T6/kk4A=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
|
@ -157,16 +172,13 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
|
|||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 h1:Uc+IZ7gYqAf/rSGFplbWBSHaGolEQlNLgMgSE3ccnIQ=
|
||||
github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813/go.mod h1:P+oSoE9yhSRvsmYyZsshflcR6ePWYLql6UU1amW13IM=
|
||||
|
@ -181,7 +193,6 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
|
|||
github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-test/deep v1.0.1/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
|
@ -190,7 +201,6 @@ github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3a
|
|||
github.com/gofrs/flock v0.7.1 h1:DP+LD/t0njgoPBvT5MJLeliUIVQR03hiKR6vezdwHlc=
|
||||
github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
|
@ -204,15 +214,25 @@ github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4er
|
|||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0 h1:Rd1kQnQu0Hq3qvJppYSG0HtP+f5LPPUiDswTLiEegLg=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
|
@ -222,6 +242,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
|||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/go-replayers/grpcreplay v0.1.0 h1:eNb1y9rZFmY4ax45uEEECSa8fsxGRU+8Bil52ASAwic=
|
||||
|
@ -236,12 +258,15 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI
|
|||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/wire v0.3.0 h1:imGQZGEVEHpje5056+K+cgdO72p0LQv2xIIFXNGUf60=
|
||||
github.com/google/wire v0.3.0/go.mod h1:i1DMg/Lu8Sz5yYl25iOdmc5CT5qusaa+zmRWs16741s=
|
||||
github.com/google/wire v0.4.0 h1:kXcsA/rIGzJImVqPdhfnr6q0xsS9gU0515q1EPpJ9fE=
|
||||
github.com/google/wire v0.4.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU=
|
||||
github.com/googleapis/gax-go v2.0.2+incompatible h1:silFMLAnr330+NRuag/VjIGF7TLp/LBrV2CJKFLWEww=
|
||||
github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
|
@ -252,9 +277,7 @@ github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7
|
|||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.2/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU=
|
||||
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
|
@ -275,7 +298,6 @@ github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa
|
|||
github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
|
||||
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE=
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
|
@ -301,7 +323,6 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl
|
|||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
|
||||
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
|
||||
|
@ -323,7 +344,6 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
|
|||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
|
@ -331,7 +351,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|||
github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
|
@ -340,15 +359,16 @@ github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LE
|
|||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149 h1:HfxbT6/JcvIljmERptWhwa8XzP7H3T+Z2N26gTsaDaA=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||
github.com/mattn/go-ieproxy v0.0.1 h1:qiyop7gCflfhwCzGyeT0gro3sF9AIg9HU98JORTkqfI=
|
||||
github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
|
@ -358,7 +378,6 @@ github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
|
|||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
|
||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
|
@ -368,7 +387,6 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
|
|||
github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc=
|
||||
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
|
||||
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
|
||||
|
@ -447,7 +465,6 @@ github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EE
|
|||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
|
@ -462,19 +479,19 @@ github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
|
|||
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/texttheater/golang-levenshtein v0.0.0-20191208221605-eb6844b05fc6 h1:9VTskZOIRf2vKF3UL8TuWElry5pgUpV1tFSe/e/0m/E=
|
||||
github.com/texttheater/golang-levenshtein v0.0.0-20191208221605-eb6844b05fc6/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7 h1:X9dsIWPuuEJlPX//UmRKophhOKCGXc46RVIGuttks68=
|
||||
github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7/go.mod h1:UxoP3EypF8JfGEjAII8jx1q8rQyDnX8qdTCs/UQBVIE=
|
||||
github.com/uber/jaeger-client-go v2.22.1+incompatible h1:NHcubEkVbahf9t3p75TOCR83gdUHXjRJvjoBh1yACsM=
|
||||
github.com/uber/jaeger-client-go v2.22.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw=
|
||||
|
@ -491,7 +508,8 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17
|
|||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/zclconf/go-cty v1.2.0 h1:sPHsy7ADcIZQP3vILvTjrh74ZA175TFP5vqiNK1UmlI=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
|
||||
github.com/zclconf/go-cty v1.3.1 h1:QIOZl+CKKdkv4l2w3lG23nNzXgLoxsWLSEdg1MlX4p0=
|
||||
github.com/zclconf/go-cty v1.3.1/go.mod h1:YO23e2L18AG+ZYQfSobnY4G65nvwvprPCxBHkufUH1k=
|
||||
|
@ -502,17 +520,15 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
|||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
gocloud.dev v0.19.0/go.mod h1:SmKwiR8YwIMMJvQBKLsC3fHNyMwXLw3PMDO+VVteJMI=
|
||||
gocloud.dev v0.19.1-0.20200517170643-46480dc2c3dd h1:XmzP/xO8nwHwO1BK2q+M2iDLYT+br/6oezs/h6ybfTg=
|
||||
gocloud.dev v0.19.1-0.20200517170643-46480dc2c3dd/go.mod h1:fvG7ZAkwaV3B1N49m64LkHoO/1bhgGBYyuK1egT06I4=
|
||||
gocloud.dev/secrets/hashivault v0.19.1-0.20200517170643-46480dc2c3dd h1:+WEbmDu8oZdj3+cZfxLn/fisLxBLPYX0R2Ju8xLXmXw=
|
||||
gocloud.dev/secrets/hashivault v0.19.1-0.20200517170643-46480dc2c3dd/go.mod h1:Us/bsVAl9RPzZR+OXgyY2LyIfyugQoNKJm+7VRZfOi0=
|
||||
gocloud.dev v0.20.0 h1:mbEKMfnyPV7W1Rj35R1xXfjszs9dXkwSOq2KoFr25g8=
|
||||
gocloud.dev v0.20.0/go.mod h1:+Y/RpSXrJthIOM8uFNzWp6MRu9pFPNFEEZrQMxpkfIc=
|
||||
gocloud.dev/secrets/hashivault v0.20.0 h1:919urzRWksXrZNNqqlHvek9IE6lWvYM4m8dvFqXq4HU=
|
||||
gocloud.dev/secrets/hashivault v0.20.0/go.mod h1:2nNlZ76i4JlT9qrPVKbINB01L8BGgv4wmq2Cqyz22dA=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
|
@ -548,6 +564,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
|
|||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367 h1:0IiAsCRByjO2QjX7ZPkw5oU9x+n1YqRL802rjC0c3Aw=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
|
@ -556,6 +574,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
|||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -573,12 +593,21 @@ golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -613,11 +642,11 @@ golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190620070143-6f217b454f45/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -626,8 +655,17 @@ golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d h1:62ap6LNOjDU6uGmKXHJbSfciMoV+FeI1sRXx/pLDL44=
|
||||
golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 h1:OjiUf46hAmXblsZdnoSXsEUSKU8r1UEzcL5RVZ4gO9Y=
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -673,13 +711,25 @@ golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapK
|
|||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2 h1:L/G4KZvrQn7FWLN/LlulBtBzrLUhqjiGfTWWDmrh+IQ=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200317043434-63da46f3035e/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200601175630-2caf76543d99/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200606014950-c42cb6316fb6/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200608174601-1b747fd94509 h1:MI14dOfl3OG6Zd32w3ugsrvcUO810fDZdWakTq39dH4=
|
||||
golang.org/x/tools v0.0.0-20200608174601-1b747fd94509/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.6.0/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
|
@ -688,14 +738,21 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb
|
|||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0 h1:jz2KixHX7EcCPiQrySzPdnYT7DbINAypCqKZ1Z7GM40=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.26.0 h1:VJZ8h6E8ip82FRpQl848c5vAadxlTXrUh8RzQzSRm08=
|
||||
google.golang.org/api v0.26.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
|
@ -704,7 +761,6 @@ google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRn
|
|||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||
google.golang.org/genproto v0.0.0-20190620144150-6af8c5fc6601/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||
google.golang.org/genproto v0.0.0-20190708153700-3bdd9d9f5532/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||
google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
|
@ -719,8 +775,19 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx
|
|||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200318110522-7735f76e9fa5 h1:Bs8aCQBqwnuSvG/tB3ip/W8JLeuQt1+1ppSHYi4n9RM=
|
||||
google.golang.org/genproto v0.0.0-20200318110522-7735f76e9fa5/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200317114155-1f3552e48f24/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200325114520-5b2d0af7952b/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200603110839-e855014d5736/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482 h1:i+Aiej6cta/Frzp13/swvwz5O00kYcSe0A/C5Wd7zX8=
|
||||
google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
|
@ -734,6 +801,18 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
|
|||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0 h1:bO/TA4OxCOummhSf10siHuG7vJOiwh7SpRpFZDkOgl4=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
gopkg.in/AlecAivazis/survey.v1 v1.8.9-0.20200217094205-6773bdf39b7f h1:AQkMzsSzHWrgZWqGRpuRaRPDmyNibcXlpGcnQJ7HxZw=
|
||||
gopkg.in/AlecAivazis/survey.v1 v1.8.9-0.20200217094205-6773bdf39b7f/go.mod h1:CaHjv79TCgAvXMSFJSVgonHXYWxnhzI3eoHtnX5UgUo=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
|
@ -771,7 +850,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
|||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
pack.ag/amqp v0.11.2/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
|
|
BIN
pkg/resource/testdata/test_dir.jar
vendored
Normal file
BIN
pkg/resource/testdata/test_dir.jar
vendored
Normal file
Binary file not shown.
|
@ -21,11 +21,11 @@ import (
|
|||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
user "github.com/tweekmonster/luser"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
|
|
|
@ -88,6 +88,7 @@ publish_containers() {
|
|||
|
||||
# This publishes the SDK specific containers and uses a dispatch event to trigger a GitHub Action
|
||||
pulumictl create containers "${CLI_VERSION//v}"
|
||||
pulumictl create choco-deploy "${CLI_VERSION//v}"
|
||||
}
|
||||
|
||||
echo_header "Building Pulumi containers (${CLI_VERSION})"
|
||||
|
|
|
@ -148,6 +148,7 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H
|
|||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/texttheater/golang-levenshtein v0.0.0-20191208221605-eb6844b05fc6/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7/go.mod h1:UxoP3EypF8JfGEjAII8jx1q8rQyDnX8qdTCs/UQBVIE=
|
||||
github.com/uber/jaeger-client-go v2.22.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
|
|
|
@ -28,6 +28,7 @@ require (
|
|||
github.com/spf13/cobra v1.0.0
|
||||
github.com/stretchr/testify v1.5.1
|
||||
github.com/texttheater/golang-levenshtein v0.0.0-20191208221605-eb6844b05fc6
|
||||
github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7
|
||||
github.com/uber/jaeger-client-go v2.22.1+incompatible
|
||||
github.com/uber/jaeger-lib v2.2.0+incompatible // indirect
|
||||
go.uber.org/atomic v1.6.0 // indirect
|
||||
|
|
|
@ -25,7 +25,6 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
|
|||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
|
@ -60,7 +59,6 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
|
|||
github.com/gofrs/flock v0.7.1 h1:DP+LD/t0njgoPBvT5MJLeliUIVQR03hiKR6vezdwHlc=
|
||||
github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
|
@ -103,13 +101,11 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL
|
|||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
|
@ -178,7 +174,6 @@ github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
|
|||
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
|
@ -187,6 +182,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
|||
github.com/texttheater/golang-levenshtein v0.0.0-20191208221605-eb6844b05fc6 h1:9VTskZOIRf2vKF3UL8TuWElry5pgUpV1tFSe/e/0m/E=
|
||||
github.com/texttheater/golang-levenshtein v0.0.0-20191208221605-eb6844b05fc6/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7 h1:X9dsIWPuuEJlPX//UmRKophhOKCGXc46RVIGuttks68=
|
||||
github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7/go.mod h1:UxoP3EypF8JfGEjAII8jx1q8rQyDnX8qdTCs/UQBVIE=
|
||||
github.com/uber/jaeger-client-go v2.22.1+incompatible h1:NHcubEkVbahf9t3p75TOCR83gdUHXjRJvjoBh1yACsM=
|
||||
github.com/uber/jaeger-client-go v2.22.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw=
|
||||
|
@ -197,7 +194,6 @@ github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0B
|
|||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
|
|
|
@ -1130,6 +1130,7 @@ const (
|
|||
TarArchive // a POSIX tar archive.
|
||||
TarGZIPArchive // a POSIX tar archive that has been subsequently compressed using GZip.
|
||||
ZIPArchive // a multi-file ZIP archive.
|
||||
JARArchive // a Java JAR file
|
||||
)
|
||||
|
||||
// ArchiveExts maps from a file extension and its associated archive and/or compression format.
|
||||
|
@ -1138,6 +1139,7 @@ var ArchiveExts = map[string]ArchiveFormat{
|
|||
".tgz": TarGZIPArchive,
|
||||
".tar.gz": TarGZIPArchive,
|
||||
".zip": ZIPArchive,
|
||||
".jar": JARArchive,
|
||||
}
|
||||
|
||||
// detectArchiveFormat takes a path and infers its archive format based on the file extension.
|
||||
|
@ -1159,7 +1161,7 @@ func readArchive(ar io.ReadCloser, format ArchiveFormat) (ArchiveReader, error)
|
|||
return readTarArchive(ar)
|
||||
case TarGZIPArchive:
|
||||
return readTarGZIPArchive(ar)
|
||||
case ZIPArchive:
|
||||
case ZIPArchive, JARArchive:
|
||||
// Unfortunately, the ZIP archive reader requires ReaderAt functionality. If it's a file, we can recover this
|
||||
// with a simple stat. Otherwise, we will need to go ahead and make a copy in memory.
|
||||
var ra io.ReaderAt
|
||||
|
|
|
@ -312,7 +312,7 @@ func TestArchiveDir(t *testing.T) {
|
|||
// Go 1.10 introduced breaking changes to archive/zip and archive/tar headers
|
||||
assert.Equal(t, "489e9a9dad271922ecfbda590efc40e48788286a06bd406a357ab8d13f0b6abf", arch.Hash)
|
||||
}
|
||||
validateTestDirArchive(t, arch)
|
||||
validateTestDirArchive(t, arch, 3)
|
||||
}
|
||||
|
||||
func TestArchiveTar(t *testing.T) {
|
||||
|
@ -320,7 +320,7 @@ func TestArchiveTar(t *testing.T) {
|
|||
arch, err := NewPathArchive("../../../../pkg/resource/testdata/test_dir.tar")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "c618d74a40f87de3092ca6a6c4cca834aa5c6a3956c6ceb2054b40d04bb4cd76", arch.Hash)
|
||||
validateTestDirArchive(t, arch)
|
||||
validateTestDirArchive(t, arch, 3)
|
||||
}
|
||||
|
||||
func TestArchiveTgz(t *testing.T) {
|
||||
|
@ -328,7 +328,7 @@ func TestArchiveTgz(t *testing.T) {
|
|||
arch, err := NewPathArchive("../../../../pkg/resource/testdata/test_dir.tgz")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "f9b33523b6a3538138aff0769ff9e7d522038e33c5cfe28b258332b3f15790c8", arch.Hash)
|
||||
validateTestDirArchive(t, arch)
|
||||
validateTestDirArchive(t, arch, 3)
|
||||
}
|
||||
|
||||
func TestArchiveZip(t *testing.T) {
|
||||
|
@ -336,7 +336,14 @@ func TestArchiveZip(t *testing.T) {
|
|||
arch, err := NewPathArchive("../../../../pkg/resource/testdata/test_dir.zip")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "343da72cec1302441efd4a490d66f861d393fb270afb3ced27f92a0d96abc068", arch.Hash)
|
||||
validateTestDirArchive(t, arch)
|
||||
validateTestDirArchive(t, arch, 3)
|
||||
}
|
||||
|
||||
func TestArchiveJar(t *testing.T) {
|
||||
arch, err := NewPathArchive("../../../../pkg/resource/testdata/test_dir.jar")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "dfb9eb69f433564b07df524068621c5ac65c08868e6094b8fa4ee388a5ee66e7", arch.Hash)
|
||||
validateTestDirArchive(t, arch, 4)
|
||||
}
|
||||
|
||||
func findRepositoryRoot() (string, error) {
|
||||
|
@ -463,6 +470,7 @@ func TestFileExtentionSniffing(t *testing.T) {
|
|||
assert.Equal(t, ArchiveFormat(TarArchive), detectArchiveFormat("./some/path/my.tar"))
|
||||
assert.Equal(t, ArchiveFormat(TarGZIPArchive), detectArchiveFormat("./some/path/my.tar.gz"))
|
||||
assert.Equal(t, ArchiveFormat(TarGZIPArchive), detectArchiveFormat("./some/path/my.tgz"))
|
||||
assert.Equal(t, ArchiveFormat(JARArchive), detectArchiveFormat("./some/path/my.jar"))
|
||||
assert.Equal(t, ArchiveFormat(NotArchive), detectArchiveFormat("./some/path/who.knows"))
|
||||
|
||||
// In #2589 we had cases where a file would look like it had an longer extension, because the suffix would include
|
||||
|
@ -471,6 +479,7 @@ func TestFileExtentionSniffing(t *testing.T) {
|
|||
assert.Equal(t, ArchiveFormat(TarArchive), detectArchiveFormat("./some/path/my.file.tar"))
|
||||
assert.Equal(t, ArchiveFormat(TarGZIPArchive), detectArchiveFormat("./some/path/my.file.tar.gz"))
|
||||
assert.Equal(t, ArchiveFormat(TarGZIPArchive), detectArchiveFormat("./some/path/my.file.tgz"))
|
||||
assert.Equal(t, ArchiveFormat(JARArchive), detectArchiveFormat("./some/path/my.file.jar"))
|
||||
assert.Equal(t, ArchiveFormat(NotArchive), detectArchiveFormat("./some/path/who.even.knows"))
|
||||
}
|
||||
|
||||
|
@ -487,7 +496,7 @@ func TestInvalidPathArchive(t *testing.T) {
|
|||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func validateTestDirArchive(t *testing.T, arch *Archive) {
|
||||
func validateTestDirArchive(t *testing.T, arch *Archive, expected int) {
|
||||
r, err := arch.Open()
|
||||
assert.Nil(t, err)
|
||||
defer func() {
|
||||
|
@ -518,7 +527,7 @@ func validateTestDirArchive(t *testing.T, arch *Archive) {
|
|||
subs[name] = text.String()
|
||||
}
|
||||
|
||||
assert.Equal(t, 3, len(subs))
|
||||
assert.Equal(t, expected, len(subs))
|
||||
|
||||
lorem := subs["Lorem_ipsum.txt"]
|
||||
assert.Equal(t, lorem,
|
||||
|
|
|
@ -16,8 +16,8 @@ package tools
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
user "github.com/tweekmonster/luser"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
|
|
@ -16,8 +16,8 @@ package workspace
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
user "github.com/tweekmonster/luser"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
|
|
|
@ -203,6 +203,18 @@ func makeBuiltins(primitives []*builtin) []*builtin {
|
|||
elementType: "[]map[string]" + p.Type,
|
||||
Example: fmt.Sprintf("%sMapArray{%sMap{\"baz\": %s}}", name, name, p.Example),
|
||||
})
|
||||
builtins = append(builtins, &builtin{
|
||||
Name: name + "MapMap",
|
||||
Type: "map[string]" + name + "MapInput",
|
||||
elementType: "map[string]map[string]" + p.Type,
|
||||
Example: fmt.Sprintf("%sMapMap{\"baz\": %sMap{\"baz\": %s}}", name, name, p.Example),
|
||||
})
|
||||
builtins = append(builtins, &builtin{
|
||||
Name: name + "ArrayArray",
|
||||
Type: "[]" + name + "ArrayInput",
|
||||
elementType: "[][]" + p.Type,
|
||||
Example: fmt.Sprintf("%sArrayArray{%sArray{%s}}", name, name, p.Example),
|
||||
})
|
||||
}
|
||||
|
||||
nameToBuiltin := map[string]*builtin{}
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -521,7 +521,7 @@ export function output<T>(val: Input<T | undefined>): Output<Unwrap<T | undefine
|
|||
}
|
||||
|
||||
/**
|
||||
* [secret] behaves the same as [output] except the resturned output is marked as contating sensitive data.
|
||||
* [secret] behaves the same as [output] except the returned output is marked as contating sensitive data.
|
||||
*/
|
||||
export function secret<T>(val: Input<T>): Output<Unwrap<T>>;
|
||||
export function secret<T>(val: Input<T> | undefined): Output<Unwrap<T | undefined>>;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
// tslint:disable
|
||||
|
||||
import * as assert from "assert";
|
||||
import { all, output, Output, unknown } from "../index";
|
||||
import { all, output, Output, Resource, unknown } from "../index";
|
||||
import { asyncTest } from "./util";
|
||||
|
||||
function test(val: any, expected: any) {
|
||||
|
@ -51,7 +51,7 @@ function testResources(val: any, expected: any, resources: TestResource[], allRe
|
|||
assert.deepStrictEqual(asyncResources, new Set(allResources));
|
||||
|
||||
for (const res of syncResources) {
|
||||
if (!asyncResources.has(<TestResource>res)) {
|
||||
if (!asyncResources.has(<Resource><any>res)) {
|
||||
assert.fail(`async resources did not contain: ${(<TestResource><any>res).name}`)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -178,7 +178,7 @@ func (host *pythonLanguageHost) Run(ctx context.Context, req *pulumirpc.RunReque
|
|||
virtualenv = filepath.Join(cwd, virtualenv)
|
||||
}
|
||||
if !python.IsVirtualEnv(virtualenv) {
|
||||
return nil, errors.Errorf("%q doesn't appear to be a virtual environment", virtualenv)
|
||||
return nil, python.NewVirtualEnvError(host.virtualenv, virtualenv)
|
||||
}
|
||||
cmd = python.VirtualEnvCommand(virtualenv, "python", args...)
|
||||
} else {
|
||||
|
|
11
sdk/python/dist/pulumi-analyzer-policy-python
vendored
11
sdk/python/dist/pulumi-analyzer-policy-python
vendored
|
@ -34,7 +34,16 @@ if [ -n "${virtualenv:-}" ] ; then
|
|||
# Run python from the virtual environment.
|
||||
"$virtualenv/bin/python" -u -m pulumi.policy "$1" "$2"
|
||||
else
|
||||
echo "\"$virtualenv\" doesn't appear to be a virtual environment"
|
||||
if [ -d "$virtualenv" ]; then
|
||||
1>&2 echo "The 'virtualenv' option in PulumiPolicy.yaml is set to \"$virtualenv\", but \"$virtualenv\" doesn't appear to be a virtual environment."
|
||||
else
|
||||
1>&2 echo "The 'virtualenv' option in PulumiPolicy.yaml is set to \"$virtualenv\", but \"$virtualenv\" doesn't exist."
|
||||
fi
|
||||
1>&2 echo "Run the following commands to create the virtual environment and install dependencies into it:"
|
||||
1>&2 echo " 1. python3 -m venv $virtualenv"
|
||||
1>&2 echo " 2. $virtualenv/bin/python -m pip install --upgrade pip setuptools wheel"
|
||||
1>&2 echo " 3. $virtualenv/bin/python -m pip install -r $PWD/requirements.txt"
|
||||
1>&2 echo "For more information see: https://www.pulumi.com/docs/intro/languages/python/#virtual-environments"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
|
|
|
@ -28,7 +28,12 @@ if defined pulumi_runtime_python_virtualenv (
|
|||
"%pulumi_runtime_python_virtualenv%\Scripts\python.exe" -u -m pulumi.policy %pulumi_policy_python_engine_address% %pulumi_policy_python_program%
|
||||
exit /B
|
||||
) else (
|
||||
echo "%pulumi_runtime_python_virtualenv%" doesn't appear to be a virtual environment
|
||||
echo The 'virtualenv' option in PulumiPolicy.yaml is set to %pulumi_runtime_python_virtualenv%, but %pulumi_runtime_python_virtualenv% doesn't appear to be a virtual environment. 1>&2
|
||||
echo Run the following commands to create the virtual environment and install dependencies into it: 1>&2
|
||||
echo 1. python -m venv %pulumi_runtime_python_virtualenv% 1>&2
|
||||
echo 2. %pulumi_runtime_python_virtualenv%\Scripts\python.exe -m pip install --upgrade pip setuptools wheel 1>&2
|
||||
echo 3. %pulumi_runtime_python_virtualenv%\Scripts\python.exe -m pip install -r %cd%\requirements.txt 1>&2
|
||||
echo For more information see: https://www.pulumi.com/docs/intro/languages/python/#virtual-environments 1>&2
|
||||
exit 1
|
||||
)
|
||||
) else (
|
||||
|
|
11
sdk/python/dist/pulumi-resource-pulumi-python
vendored
11
sdk/python/dist/pulumi-resource-pulumi-python
vendored
|
@ -22,7 +22,16 @@ if [ -n "${PULUMI_RUNTIME_VIRTUALENV:-}" ] ; then
|
|||
# Run python from the virtual environment.
|
||||
"$PULUMI_RUNTIME_VIRTUALENV/bin/python" -u -m pulumi.dynamic $@
|
||||
else
|
||||
echo "\"$PULUMI_RUNTIME_VIRTUALENV\" doesn't appear to be a virtual environment"
|
||||
if [ -d "$PULUMI_RUNTIME_VIRTUALENV" ]; then
|
||||
1>&2 echo "The 'virtualenv' option in Pulumi.yaml is set to \"$PULUMI_RUNTIME_VIRTUALENV\", but \"$PULUMI_RUNTIME_VIRTUALENV\" doesn't appear to be a virtual environment."
|
||||
else
|
||||
1>&2 echo "The 'virtualenv' option in Pulumi.yaml is set to \"$PULUMI_RUNTIME_VIRTUALENV\", but \"$PULUMI_RUNTIME_VIRTUALENV\" doesn't exist."
|
||||
fi
|
||||
1>&2 echo "Run the following commands to create the virtual environment and install dependencies into it:"
|
||||
1>&2 echo " 1. python3 -m venv $PULUMI_RUNTIME_VIRTUALENV"
|
||||
1>&2 echo " 2. $PULUMI_RUNTIME_VIRTUALENV/bin/python -m pip install --upgrade pip setuptools wheel"
|
||||
1>&2 echo " 3. $PULUMI_RUNTIME_VIRTUALENV/bin/python -m pip install -r $PWD/requirements.txt"
|
||||
1>&2 echo "For more information see: https://www.pulumi.com/docs/intro/languages/python/#virtual-environments"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
|
|
|
@ -11,7 +11,12 @@ if defined PULUMI_RUNTIME_VIRTUALENV (
|
|||
"%PULUMI_RUNTIME_VIRTUALENV%\Scripts\python.exe" -u -m pulumi.dynamic %*
|
||||
exit /B
|
||||
) else (
|
||||
echo "%PULUMI_RUNTIME_VIRTUALENV%" doesn't appear to be a virtual environment
|
||||
echo The 'virtualenv' option in Pulumi.yaml is set to %PULUMI_RUNTIME_VIRTUALENV%, but %PULUMI_RUNTIME_VIRTUALENV% doesn't appear to be a virtual environment. 1>&2
|
||||
echo Run the following commands to create the virtual environment and install dependencies into it: 1>&2
|
||||
echo 1. python -m venv %PULUMI_RUNTIME_VIRTUALENV% 1>&2
|
||||
echo 2. %PULUMI_RUNTIME_VIRTUALENV%\Scripts\python.exe -m pip install --upgrade pip setuptools wheel 1>&2
|
||||
echo 3. %PULUMI_RUNTIME_VIRTUALENV%\Scripts\python.exe -m pip install -r %cd%\requirements.txt 1>&2
|
||||
echo For more information see: https://www.pulumi.com/docs/intro/languages/python/#virtual-environments 1>&2
|
||||
exit 1
|
||||
)
|
||||
) else (
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue