Skip to content

Commit

Permalink
Add ignore changes for bootstrapClusterCreatorAdminPermissions of EKS…
Browse files Browse the repository at this point in the history
… clusters (#1292)
  • Loading branch information
flostadler authored Aug 8, 2024
1 parent 257f0d6 commit 4e11388
Show file tree
Hide file tree
Showing 5 changed files with 2,415 additions and 0 deletions.
4 changes: 4 additions & 0 deletions nodejs/eks/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,10 @@ export function createCore(
{
parent,
provider: args.creationRoleProvider ? args.creationRoleProvider.provider : provider,
// ignore changes to the bootstrapClusterCreatorAdminPermissions field because it has bi-modal default behavior
// in upstream and would cause replacements for users upgrading from older versions of the EKS provider (<=2.7.3).
// See https://github.com/pulumi/pulumi-aws/issues/3997#issuecomment-2223201333 for more details.
ignoreChanges: ["accessConfig.bootstrapClusterCreatorAdminPermissions"],
},
);

Expand Down
130 changes: 130 additions & 0 deletions provider/provider_test.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package provider

import (
"encoding/json"
"os"
"path/filepath"
"testing"

"fmt"

"github.com/pulumi/providertest"
"github.com/pulumi/providertest/optproviderupgrade"
"github.com/pulumi/providertest/pulumitest"
"github.com/pulumi/providertest/pulumitest/assertpreview"
"github.com/pulumi/providertest/pulumitest/optnewstack"
"github.com/pulumi/providertest/pulumitest/opttest"
"github.com/pulumi/pulumi/sdk/v3/go/common/apitype"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -157,3 +161,129 @@ func testProviderUpgrade(t *testing.T, example string) {
)
assertpreview.HasNoReplacements(t, result)
}

type testProviderCodeChangesOptions struct {
region string
firstProgram []byte
secondProgram []byte
firstProgramOptions []opttest.Option
secondProgramOptions []opttest.Option
}

// testProviderCodeChanges tests two different runs of a pulumi program. This allow you to run
// pulumi up with an initial program, change the code of the program and then run another pulumi command
func testProviderCodeChanges(t *testing.T, opts *testProviderCodeChangesOptions) *pulumitest.PulumiTest {
if testing.Short() {
t.Skip("Skipping provider tests in short mode")
}
t.Parallel()
t.Helper()

workdir := t.TempDir()
cacheDir := filepath.Join("testdata", "recorded", "TestProviderUpgrade", t.Name())
err := os.MkdirAll(cacheDir, 0755)
require.NoError(t, err)
stackExportFile := filepath.Join(cacheDir, "stack.json")

err = os.WriteFile(filepath.Join(workdir, "Pulumi.yaml"), opts.firstProgram, 0o600)
require.NoError(t, err)

options := []opttest.Option{
opttest.SkipInstall(),
opttest.NewStackOptions(optnewstack.DisableAutoDestroy()),
}

if opts.firstProgramOptions != nil {
options = append(options, opts.firstProgramOptions...)
}

pt := pulumitest.NewPulumiTest(t, workdir, options...)
region := "us-west-2"
if opts != nil && opts.region != "" {
region = opts.region
}
pt.SetConfig("aws:region", region)

var export *apitype.UntypedDeployment
export, err = tryReadStackExport(stackExportFile)
if err != nil {
pt.Up()
grpcLog := pt.GrpcLog()
grpcLogPath := filepath.Join(cacheDir, "grpc.json")
t.Logf("writing grpc log to %s", grpcLogPath)
err = grpcLog.WriteTo(grpcLogPath)
require.NoError(t, err)

e := pt.ExportStack()
export = &e
err = writeStackExport(stackExportFile, export, true)
require.NoError(t, err)
}

secondOptions := []opttest.Option{
opttest.SkipInstall(),
opttest.NewStackOptions(optnewstack.EnableAutoDestroy()),
}

if opts.secondProgramOptions != nil {
secondOptions = append(options, opts.secondProgramOptions...)
}
err = os.WriteFile(filepath.Join(workdir, "Pulumi.yaml"), opts.secondProgram, 0o600)
require.NoError(t, err)
secondTest := pulumitest.NewPulumiTest(t, workdir, secondOptions...)
secondTest.SetConfig("aws:region", region)
secondTest.ImportStack(*export)

return secondTest
}

// writeStackExport writes the stack export to the given path creating any directories needed.
func writeStackExport(path string, snapshot *apitype.UntypedDeployment, overwrite bool) error {
if snapshot == nil {
return fmt.Errorf("stack export must not be nil")
}
dir := filepath.Dir(path)
err := os.MkdirAll(dir, 0755)
if err != nil {
return err
}
stackBytes, err := json.MarshalIndent(snapshot, "", " ")
if err != nil {
return err
}
pathExists, err := exists(path)
if err != nil {
return err
}
if pathExists && !overwrite {
return fmt.Errorf("stack export already exists at %s", path)
}
//nolint:gosec // 0644 is the correct permission for this file
return os.WriteFile(path, stackBytes, 0644)
}

// tryReadStackExport reads a stack export from the given file path.
// If the file does not exist, returns nil, nil.
func tryReadStackExport(path string) (*apitype.UntypedDeployment, error) {
stackBytes, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("failed to read stack export at %s: %v", path, err)
}
var stackExport apitype.UntypedDeployment
err = json.Unmarshal(stackBytes, &stackExport)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal stack export at %s: %v", path, err)
}
return &stackExport, nil
}

func exists(filePath string) (bool, error) {
_, err := os.Stat(filePath)
switch {
case err == nil:
return true, nil
case !os.IsNotExist(err):
return false, err
}
return false, nil
}
86 changes: 86 additions & 0 deletions provider/provider_yaml_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package provider

import (
"os"
"path/filepath"
"testing"

"fmt"

"github.com/pulumi/providertest/pulumitest/assertpreview"
"github.com/pulumi/providertest/pulumitest/opttest"
"github.com/stretchr/testify/assert"
)

func TestEksAuthModeUpgrade(t *testing.T) {
t.Parallel()
if testing.Short() {
t.Skipf("Skipping in testing.Short() mode, assuming this is a CI run without credentials")
}
const firstYaml = `
name: eksClusterAuthModeUpgrade
runtime: yaml
resources:
Vpc:
type: awsx:ec2:Vpc
properties:
subnetSpecs:
- type: Public
natGateways:
strategy: None
EksCluster:
type: eks:Cluster
properties:
vpcId: ${Vpc.vpcId}
skipDefaultNodeGroup: true
publicSubnetIds: ${Vpc.publicSubnetIds}
`
const secondYaml = `
name: eksClusterAuthModeUpgrade
runtime: yaml
resources:
Vpc:
type: awsx:ec2:Vpc
properties:
subnetSpecs:
- type: Public
natGateways:
strategy: None
EksCluster:
type: eks:Cluster
properties:
vpcId: ${Vpc.vpcId}
skipDefaultNodeGroup: true
publicSubnetIds: ${Vpc.publicSubnetIds}
authenticationMode: CONFIG_MAP
`

var (
providerName = "eks"
baselineVersion = "2.7.3"
)
cwd, err := os.Getwd()
assert.NoError(t, err)

firstProgram := []byte(firstYaml)
secondProgram := []byte(secondYaml)
// test that we can upgrade from the previous version which accepted a string for `subnetIds`
// to the new version which accepts a list
t.Run("upgrade", func(t *testing.T) {
pulumiTest := testProviderCodeChanges(t, &testProviderCodeChangesOptions{
firstProgram: firstProgram,
firstProgramOptions: []opttest.Option{
opttest.DownloadProviderVersion(providerName, baselineVersion),
},
secondProgram: secondProgram,
secondProgramOptions: []opttest.Option{
opttest.LocalProviderPath("eks", filepath.Join(cwd, "..", "bin")),
},
})

res := pulumiTest.Preview()
fmt.Printf("stdout: %s \n", res.StdOut)
fmt.Printf("stderr: %s \n", res.StdErr)
assertpreview.HasNoReplacements(t, res)
})
}
Loading

0 comments on commit 4e11388

Please sign in to comment.