Skip to content

Commit

Permalink
Ensure the k8s and application-engine current contexts are mutual exc…
Browse files Browse the repository at this point in the history
…lusive

Signed-off-by: Prem Kumar Kalle <[email protected]>
  • Loading branch information
prkalle committed Oct 5, 2023
1 parent 64cee83 commit 122d2b2
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 2 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ replace cloud.google.com/go => cloud.google.com/go v0.102.1

replace github.com/vmware-tanzu/tanzu-cli/test/e2e/framework => ./test/e2e/framework

replace github.com/vmware-tanzu/tanzu-plugin-runtime => ../tanzu-plugin-runtime

require (
github.com/AlecAivazis/survey/v2 v2.3.6
github.com/Masterminds/semver v1.5.0
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -735,8 +735,6 @@ github.com/vmware-tanzu/tanzu-framework/apis/run v0.0.0-20230419030809-7081502eb
github.com/vmware-tanzu/tanzu-framework/apis/run v0.0.0-20230419030809-7081502ebf68/go.mod h1:e1Uef+Ux5BIHpYwqbeP2ZZmOzehBcez2vUEWXHe+xHE=
github.com/vmware-tanzu/tanzu-framework/capabilities/client v0.0.0-20230523145612-1c6fbba34686 h1:VcuXqUXFxm5WDqWkzAlU/6cJXua0ozELnqD59fy7J6E=
github.com/vmware-tanzu/tanzu-framework/capabilities/client v0.0.0-20230523145612-1c6fbba34686/go.mod h1:AFGOXZD4tH+KhpmtV0VjWjllXhr8y57MvOsIxTtywc4=
github.com/vmware-tanzu/tanzu-plugin-runtime v1.1.0-dev.0.20231002160823-1da8552a1589 h1:D6B0U5whz3LZvMokKpxYBBHNzkdbhPQOpNKBuJ/B+ho=
github.com/vmware-tanzu/tanzu-plugin-runtime v1.1.0-dev.0.20231002160823-1da8552a1589/go.mod h1:wMK/qpJjU7hytDAGt3FX5/iGdlUK8TsJLu36pCr+Zvk=
github.com/xanzy/go-gitlab v0.83.0 h1:37p0MpTPNbsTMKX/JnmJtY8Ch1sFiJzVF342+RvZEGw=
github.com/xanzy/go-gitlab v0.83.0/go.mod h1:5ryv+MnpZStBH8I/77HuQBsMbBGANtVpLWC15qOjWAw=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
Expand Down
9 changes: 9 additions & 0 deletions pkg/command/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/vmware-tanzu/tanzu-cli/pkg/pluginmanager"
"github.com/vmware-tanzu/tanzu-cli/pkg/pluginsupplier"
"github.com/vmware-tanzu/tanzu-cli/pkg/telemetry"
"github.com/vmware-tanzu/tanzu-cli/pkg/utils"

"github.com/vmware-tanzu/tanzu-plugin-runtime/config"
configtypes "github.com/vmware-tanzu/tanzu-plugin-runtime/config/types"
Expand Down Expand Up @@ -163,6 +164,14 @@ func newRootCmd() *cobra.Command {
}
return nil
},
PersistentPostRunE: func(cmd *cobra.Command, args []string) error {
// Ensure mutual exclusion in current contexts just in case if any plugins with old
// plugin-runtime sets k8s context as current when tae context is already set as current
if err := utils.EnsureMutualExclusiveCurrentContexts(); err != nil {
return err
}
return nil
},
}
return rootCmd
}
Expand Down
55 changes: 55 additions & 0 deletions pkg/fakes/config/tanzu_config_ng_2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
contexts:
- name: test-mc-context
target: kubernetes
clusterOpts:
isManagementCluster: true
endpoint: test-endpoint
path: test-path
context: test-mc-context
discoverySources:
- gcp:
name: test
bucket: test-bucket
manifestPath: test-manifest-path
- name: test-use-context
target: mission-control
globalOpts:
endpoint: test-endpoint2
auth:
IDToken: test-id-token
accessToken: test-access-token
type: api-token
userName: test-user-name
refresh_token: test-refresh-token
- name: test-tmc-context
target: mission-control
globalOpts:
endpoint: test-endpoint3
auth:
IDToken: test-id-token2
accessToken: test-access-token2
type: api-token2
userName: test-user-name2
refresh_token: test-refresh-token2
- name: test-tae-context
target: application-engine
globalOpts:
endpoint: tae-endpoint
auth:
IDToken: test-id-token
accessToken: test-access-token
type: api-token
userName: test-user-name
refresh_token: test-refresh-token
clusterOpts:
isManagementCluster: false
endpoint: kube-endpoint
path: dummy/path
context: dummy-context
additionalMetadata:
taeProjectName: dummyP
taeOrgID: dummyO
currentContext:
kubernetes: test-mc-context
mission-control: test-tmc-context
application-engine: test-tae-context
7 changes: 7 additions & 0 deletions pkg/pluginmanager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,13 @@ func doDeletePluginFromCatalog(pluginName string, target configtypes.Target, cat
// If the central-repo is disabled, all discovered plugins will be installed.
func SyncPlugins() error {
log.Info("Checking for required plugins...")
// ensure the k8s and tae current contexts are mutually exclusive.
// This is required as plugins could call syncPlugins through plugin-runtime
err := utils.EnsureMutualExclusiveCurrentContexts()
if err != nil {
return err
}

errList := make([]error, 0)
// We no longer sync standalone plugins.
// With a centralized approach to discovering plugins, synchronizing
Expand Down
18 changes: 18 additions & 0 deletions pkg/utils/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ package utils

import (
"strings"

"github.com/vmware-tanzu/tanzu-plugin-runtime/config"
configtypes "github.com/vmware-tanzu/tanzu-plugin-runtime/config/types"
)

// ContainsString checks the string contains in string array
Expand All @@ -30,3 +33,18 @@ func ContainsString(arr []string, str string) bool {
func GenerateKey(parts ...string) string {
return strings.Join(parts, ":")
}

// EnsureMutualExclusiveCurrentContexts ensures mutual exclusive behavior among k8s and tae current contexts,
// i.e, if both k8s and tae current contexts types are set (a case where plugin using old plugin-runtime API
// can set k8s current context though tae current context is set by CLI or plugin with latest plugin-runtime
// in config file) it would remove the tae current context to maintain backward compatibility
func EnsureMutualExclusiveCurrentContexts() error {
ccmap, err := config.GetAllCurrentContextsMap()
if err != nil {
return err
}
if ccmap[configtypes.TargetK8s] != nil && ccmap[configtypes.TargetTAE] != nil {
return config.RemoveCurrentContext(configtypes.TargetTAE)
}
return nil
}
90 changes: 90 additions & 0 deletions pkg/utils/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@
package utils

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

"github.com/otiai10/copy"
"github.com/stretchr/testify/assert"

"github.com/vmware-tanzu/tanzu-plugin-runtime/config"
configtypes "github.com/vmware-tanzu/tanzu-plugin-runtime/config/types"
)

// TestContainsString tests the ContainsString function.
Expand Down Expand Up @@ -87,3 +95,85 @@ func TestGenerateKey(t *testing.T) {
})
}
}

func setupMultiConcurrentContexts(t *testing.T) func() {
tkgConfigFile, err := os.CreateTemp("", "config")
assert.NoError(t, err)
err = copy.Copy(filepath.Join("..", "fakes", "config", "tanzu_config.yaml"), tkgConfigFile.Name())
assert.NoError(t, err, "Error while copying tanzu config file for testing")
os.Setenv("TANZU_CONFIG", tkgConfigFile.Name())

tkgConfigFileNG, err := os.CreateTemp("", "config_ng")
assert.NoError(t, err)
os.Setenv("TANZU_CONFIG_NEXT_GEN", tkgConfigFileNG.Name())
err = copy.Copy(filepath.Join("..", "fakes", "config", "tanzu_config_ng_2.yaml"), tkgConfigFileNG.Name())
assert.NoError(t, err, "Error while copying tanzu-ng config file for testing")

cleanup := func() {
err = os.Remove(tkgConfigFile.Name())
assert.NoError(t, err)
err = os.Unsetenv("TANZU_CONFIG")
assert.NoError(t, err)

err = os.Remove(tkgConfigFileNG.Name())
assert.NoError(t, err)
err = os.Unsetenv("TANZU_CONFIG_NEXT_GEN")
assert.NoError(t, err)
}
return cleanup
}

// TestGenerateKey tests the GenerateKey function.
func TestEnsureMutualExclusiveCurrentContexts(t *testing.T) {
cleanup := setupMultiConcurrentContexts(t)

defer func() {
cleanup()
}()

// it should remove the tae current context and keep k8s and tmc current context
err := EnsureMutualExclusiveCurrentContexts()
assert.NoError(t, err)

ccmap, err := config.GetAllCurrentContextsMap()
assert.NoError(t, err)
assert.Equal(t, ccmap[configtypes.TargetK8s].Name, "test-mc-context")
assert.Equal(t, ccmap[configtypes.TargetTMC].Name, "test-tmc-context")
assert.Nil(t, ccmap[configtypes.TargetTAE])

// if there is only k8s current context, calling again should not affect the current contexts
err = EnsureMutualExclusiveCurrentContexts()
assert.NoError(t, err)

ccmap, err = config.GetAllCurrentContextsMap()
assert.NoError(t, err)
assert.Equal(t, ccmap[configtypes.TargetK8s].Name, "test-mc-context")
assert.Equal(t, ccmap[configtypes.TargetTMC].Name, "test-tmc-context")
assert.Nil(t, ccmap[configtypes.TargetTAE])

// if there is only tae current context, calling again should not affect the current contexts
err = config.SetCurrentContext("test-tae-context")
assert.NoError(t, err)

err = EnsureMutualExclusiveCurrentContexts()
assert.NoError(t, err)

ccmap, err = config.GetAllCurrentContextsMap()
assert.NoError(t, err)
assert.Nil(t, ccmap[configtypes.TargetK8s])
assert.Equal(t, ccmap[configtypes.TargetTMC].Name, "test-tmc-context")
assert.Equal(t, ccmap[configtypes.TargetTAE].Name, "test-tae-context")

// if there are no current context, calling again should not affect the current contexts
err = config.RemoveCurrentContext(configtypes.TargetTAE)
assert.NoError(t, err)
err = config.RemoveCurrentContext(configtypes.TargetTMC)
assert.NoError(t, err)

err = EnsureMutualExclusiveCurrentContexts()
assert.NoError(t, err)

ccmap, err = config.GetAllCurrentContextsMap()
assert.NoError(t, err)
assert.Equal(t, len(ccmap), 0)
}

0 comments on commit 122d2b2

Please sign in to comment.