Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CEIP Opt-In support #143

Merged
merged 1 commit into from
Apr 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ test: fmt ## Run Tests

.PHONY: e2e-cli-core ## Execute all CLI Core E2E Tests
e2e-cli-core: e2e-cli-plugin-compatibility-test e2e-cli-tmc-test e2e-cli-plugin-lifecycle-test
export TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER="Yes" ; \
${GO} test `go list ./test/e2e/... | grep -v test/e2e/context/tmc | grep -v test/e2e/plugins_compatibility | grep -v test/e2e/plugin_lifecycle` -timeout 60m -race -coverprofile coverage.txt ${GOTEST_VERBOSE}

.PHONY: e2e-cli-plugin-compatibility-test ## Execute CLI Core Plugin Compatibility E2E test cases
Expand All @@ -204,6 +205,7 @@ e2e-cli-plugin-compatibility-test:
else \
export TANZU_CLI_PRE_RELEASE_REPO_IMAGE=$(TANZU_CLI_E2E_TEST_CENTRAL_REPO_URL) ; \
export TANZU_CLI_PLUGIN_DISCOVERY_IMAGE_SIGNATURE_VERIFICATION_SKIP_LIST=$(TANZU_CLI_E2E_TEST_CENTRAL_REPO_URL) ; \
export TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER="Yes" ; \
${GO} test ./test/e2e/plugins_compatibility -timeout 60m -race -coverprofile coverage.txt ${GOTEST_VERBOSE} ; \
fi

Expand All @@ -215,6 +217,7 @@ e2e-cli-plugin-lifecycle-test:
export TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_URL=$(TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_URL) ; \
export TANZU_CLI_PRE_RELEASE_REPO_IMAGE=$(TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_URL) ; \
export TANZU_CLI_PLUGIN_DISCOVERY_IMAGE_SIGNATURE_VERIFICATION_SKIP_LIST=$(TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_URL) ; \
export TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER="Yes" ; \
${GO} test ./test/e2e/plugin_lifecycle -timeout 60m -race -coverprofile coverage.txt ${GOTEST_VERBOSE} ; \
fi

Expand All @@ -223,6 +226,7 @@ e2e-cli-tmc-test:
@if [ "${TANZU_API_TOKEN}" = "" ] && [ "$(TANZU_CLI_TMC_UNSTABLE_URL)" = "" ]; then \
echo "***Skipping TMC specific e2e tests cases because environment variables TANZU_API_TOKEN and TANZU_CLI_TMC_UNSTABLE_URL are not set***" ; \
else \
export TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER="Yes" ; \
${GO} test ./test/e2e/context/tmc -timeout 60m -race -coverprofile coverage.txt ${GOTEST_VERBOSE} ; \
fi

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ require (
github.com/tj/assert v0.0.3
github.com/vmware-tanzu/carvel-ytt v0.40.0
github.com/vmware-tanzu/tanzu-framework/capabilities/client v0.0.0-20230130173350-eeda69d80a24
github.com/vmware-tanzu/tanzu-plugin-runtime v0.0.2-0.20230321210330-330c29284da6
github.com/vmware-tanzu/tanzu-plugin-runtime v0.0.2-0.20230403161015-4575b79c9655
go.pinniped.dev v0.20.0
go.uber.org/multierr v1.8.0
golang.org/x/mod v0.8.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1286,8 +1286,8 @@ github.com/vmware-tanzu/tanzu-framework/apis/run v0.0.0-20221207131309-7323ca04b
github.com/vmware-tanzu/tanzu-framework/apis/run v0.0.0-20221207131309-7323ca04b86c/go.mod h1:ukZpKQ0hf5bjWdJLjn2M6qXP+9giZWQPxt8nOfrCR+o=
github.com/vmware-tanzu/tanzu-framework/capabilities/client v0.0.0-20230130173350-eeda69d80a24 h1:zz3XDCLPqvhtx8OMMRNjSn/krxhqkYnuw9Z9DBh6ruA=
github.com/vmware-tanzu/tanzu-framework/capabilities/client v0.0.0-20230130173350-eeda69d80a24/go.mod h1:rcIfoGpdav3evsyEMMzYH0xhGZOkIy+Ra3koypM8Aco=
github.com/vmware-tanzu/tanzu-plugin-runtime v0.0.2-0.20230321210330-330c29284da6 h1:w+lpvLqFtRr0NpmAHtRnMi7hLOG8x0DZ8sE+iVX+RRs=
github.com/vmware-tanzu/tanzu-plugin-runtime v0.0.2-0.20230321210330-330c29284da6/go.mod h1:y70TLdev7MX8K6CkAA7h92qVUDyjbX8y9/J5q4UmhRs=
github.com/vmware-tanzu/tanzu-plugin-runtime v0.0.2-0.20230403161015-4575b79c9655 h1:ZAkEx5/PIwVuapIJ1IH4QJCjLX2TXGXOu1CaO9is4t4=
github.com/vmware-tanzu/tanzu-plugin-runtime v0.0.2-0.20230403161015-4575b79c9655/go.mod h1:y70TLdev7MX8K6CkAA7h92qVUDyjbX8y9/J5q4UmhRs=
github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
github.com/xanzy/go-gitlab v0.73.1 h1:UMagqUZLJdjss1SovIC+kJCH4k2AZWXl58gJd38Y/hI=
github.com/xanzy/go-gitlab v0.73.1/go.mod h1:d/a0vswScO7Agg1CZNz15Ic6SSvBG9vfw8egL99t4kA=
Expand Down
93 changes: 93 additions & 0 deletions pkg/command/ceip_participation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Copyright 2023 VMware, Inc. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package command

import (
"strconv"
"strings"

"github.com/pkg/errors"
"github.com/spf13/cobra"

"github.com/vmware-tanzu/tanzu-cli/pkg/cli"
"github.com/vmware-tanzu/tanzu-plugin-runtime/component"
configlib "github.com/vmware-tanzu/tanzu-plugin-runtime/config"
"github.com/vmware-tanzu/tanzu-plugin-runtime/plugin"
)

// CeipOptOutStatus and CeipOptInStatus are constants for the CEIP opt-in/out verbiage
const (
CeipOptInStatus = "Opt-in"
CeipOptOutStatus = "Opt-out"
)

// Note(TODO:prkalle): The below ceip-participation command(experimental) added may be removed in the next release,
// If we decide to fold this functionality into existing 'tanzu telemetry' plugin

func newCEIPParticipationCmd() *cobra.Command {
var ceipParticipationCmd = &cobra.Command{
Use: "ceip-participation",
Short: "Manage CEIP Participation",
Long: "Manage CEIP Participation",
Aliases: []string{"ceip"},
Annotations: map[string]string{
"group": string(plugin.SystemCmdGroup),
},
}
ceipParticipationCmd.SetUsageFunc(cli.SubCmdUsageFunc)

ceipParticipationCmd.AddCommand(
newCEIPParticipationSetCmd(),
newCEIPParticipationGetCmd(),
)

return ceipParticipationCmd
}

func newCEIPParticipationSetCmd() *cobra.Command {
var setCmd = &cobra.Command{
Use: "set OPT_IN_BOOL",
Short: "Set the opt-in preference for CEIP",
Long: "Set the opt-in preference for CEIP",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
if !strings.EqualFold(args[0], "true") && !strings.EqualFold(args[0], "false") {
return errors.Errorf("incorrect boolean argument: %q", args[0])
}
err := configlib.SetCEIPOptIn(strconv.FormatBool(strings.EqualFold(args[0], "true")))
if err != nil {
return errors.Wrapf(err, "failed to update the configuration")
}
return nil
},
}

return setCmd
}

func newCEIPParticipationGetCmd() *cobra.Command {
var getCmd = &cobra.Command{
Use: "get",
Short: "Get the current CEIP opt-in status",
Long: "Get the current CEIP opt-in status",
RunE: func(cmd *cobra.Command, args []string) error {
optInVal, err := configlib.GetCEIPOptIn()
if err != nil {
return errors.Wrapf(err, "failed to get the CEIP opt-in status")
}
ceipStatus := ""
if optInVal == "true" {
ceipStatus = CeipOptInStatus
} else {
ceipStatus = CeipOptOutStatus
}
t := component.NewOutputWriter(cmd.OutOrStdout(), outputFormat, "CEIP-Status")
t.AddRow(ceipStatus)
t.Render()
return nil
},
}

return getCmd
}
117 changes: 117 additions & 0 deletions pkg/command/ceip_participation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright 2023 VMware, Inc. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package command

import (
"bytes"
"os"
"path/filepath"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/otiai10/copy"
)

var _ = Describe("ceip-participation command tests", func() {

Describe("ceip-participation command set/get tests", func() {
var (
tkgConfigFile *os.File
tkgConfigFileNG *os.File
err error
)

BeforeEach(func() {
tkgConfigFile, err = os.CreateTemp("", "config")
Expect(err).To(BeNil())
err = copy.Copy(filepath.Join("..", "fakes", "config", "tanzu_config.yaml"), tkgConfigFile.Name())
Expect(err).To(BeNil(), "Error while copying tanzu config file for testing")
os.Setenv("TANZU_CONFIG", tkgConfigFile.Name())

tkgConfigFileNG, err = os.CreateTemp("", "config_ng")
Expect(err).To(BeNil())
os.Setenv("TANZU_CONFIG_NEXT_GEN", tkgConfigFileNG.Name())
err = copy.Copy(filepath.Join("..", "fakes", "config", "tanzu_config_ng.yaml"), tkgConfigFileNG.Name())
Expect(err).To(BeNil(), "Error while copying tanzu config_ng.yaml file for testing")
})
AfterEach(func() {
os.Unsetenv("TANZU_CONFIG")
os.Unsetenv("TANZU_CONFIG_NEXT_GEN")
os.RemoveAll(tkgConfigFile.Name())
os.RemoveAll(tkgConfigFileNG.Name())
resetLoginCommandFlags()
})
Context("ceip-participation set to true", func() {
It("ceip-participation set should be successful and get should return status as 'Opt-in' status", func() {
prkalle marked this conversation as resolved.
Show resolved Hide resolved
ceipSetCmd := newCEIPParticipationSetCmd()
ceipSetCmd.SetArgs([]string{"true"})
err = ceipSetCmd.Execute()
Expect(err).To(BeNil())

ceipGetCmd := newCEIPParticipationGetCmd()
var out bytes.Buffer
ceipGetCmd.SetOut(&out)
err = ceipGetCmd.Execute()
Expect(err).To(BeNil())
Expect(out.String()).To(ContainSubstring("Opt-in"))

ceipSetCmd = newCEIPParticipationSetCmd()
ceipSetCmd.SetArgs([]string{"True"})
err = ceipSetCmd.Execute()
Expect(err).To(BeNil())

ceipGetCmd = newCEIPParticipationGetCmd()
out.Reset()
ceipGetCmd.SetOut(&out)
err = ceipGetCmd.Execute()
Expect(err).To(BeNil())
Expect(out.String()).To(ContainSubstring("Opt-in"))

})
})
Context("ceip-participation set to false", func() {
It("ceip-participation set should be successful and get should return status as 'Opt-out' status", func() {
ceipSetCmd := newCEIPParticipationSetCmd()
ceipSetCmd.SetArgs([]string{"false"})
err = ceipSetCmd.Execute()
Expect(err).To(BeNil())

ceipGetCmd := newCEIPParticipationGetCmd()
var out bytes.Buffer
ceipGetCmd.SetOut(&out)
err = ceipGetCmd.Execute()
Expect(err).To(BeNil())
Expect(out.String()).To(ContainSubstring("Opt-out"))

ceipSetCmd = newCEIPParticipationSetCmd()
ceipSetCmd.SetArgs([]string{"False"})
err = ceipSetCmd.Execute()
Expect(err).To(BeNil())

ceipGetCmd = newCEIPParticipationGetCmd()
out.Reset()
ceipGetCmd.SetOut(&out)
err = ceipGetCmd.Execute()
Expect(err).To(BeNil())
Expect(out.String()).To(ContainSubstring("Opt-out"))
})
})
Context("ceip-participation set to invalid boolean argument", func() {
It("ceip-participation set should fail", func() {
ceipSetCmd := newCEIPParticipationSetCmd()
ceipSetCmd.SetArgs([]string{"fakebool"})
err = ceipSetCmd.Execute()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("incorrect boolean argument:"))
})
})
Context("ceip-participation set without argument", func() {
It("ceip-participation set should fail", func() {
ceipSetCmd := newCEIPParticipationSetCmd()
err = ceipSetCmd.Execute()
Expect(err).To(HaveOccurred())
})
})
})

})
9 changes: 8 additions & 1 deletion pkg/command/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ func TestPluginList(t *testing.T) {
assert.Nil(t, err)
defer os.RemoveAll(dir)
os.Setenv("TEST_CUSTOM_CATALOG_CACHE_DIR", dir)
os.Setenv("TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER", "No")

// Always turn on the context feature
featureArray := strings.Split(constants.FeatureContextCommand, ".")
Expand Down Expand Up @@ -209,6 +210,7 @@ func TestPluginList(t *testing.T) {
os.Unsetenv("TEST_CUSTOM_CATALOG_CACHE_DIR")
os.Unsetenv("TANZU_CONFIG")
os.Unsetenv("TANZU_CONFIG_NEXT_GEN")
os.Unsetenv("TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER")
}
}

Expand Down Expand Up @@ -245,7 +247,7 @@ func TestDeletePlugin(t *testing.T) {
assert.Nil(t, err)
defer os.RemoveAll(dir)
os.Setenv("TEST_CUSTOM_CATALOG_CACHE_DIR", dir)

os.Setenv("TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER", "No")
var completionType uint8
t.Run(spec.test, func(t *testing.T) {
assert := assert.New(t)
Expand Down Expand Up @@ -284,6 +286,7 @@ func TestDeletePlugin(t *testing.T) {
}
})
os.Unsetenv("TEST_CUSTOM_CATALOG_CACHE_DIR")
os.Unsetenv("TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER")
}
}

Expand Down Expand Up @@ -355,6 +358,7 @@ func TestInstallPlugin(t *testing.T) {
tkgConfigFileNG, err := os.CreateTemp("", "config_ng")
assert.Nil(err)
os.Setenv("TANZU_CONFIG_NEXT_GEN", tkgConfigFileNG.Name())
os.Setenv("TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER", "No")

// Bypass the environment variable for testing
err = os.Setenv(constants.ConfigVariablePreReleasePluginRepoImage, pluginmanager.PreReleasePluginRepoImageBypass)
Expand All @@ -367,6 +371,7 @@ func TestInstallPlugin(t *testing.T) {
defer func() {
os.Unsetenv("TANZU_CONFIG")
os.Unsetenv("TANZU_CONFIG_NEXT_GEN")
os.Unsetenv("TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER")
os.RemoveAll(tkgConfigFile.Name())
os.RemoveAll(tkgConfigFileNG.Name())
}()
Expand Down Expand Up @@ -415,6 +420,7 @@ func TestUpgradePlugin(t *testing.T) {
tkgConfigFileNG, err := os.CreateTemp("", "config_ng")
assert.Nil(err)
os.Setenv("TANZU_CONFIG_NEXT_GEN", tkgConfigFileNG.Name())
os.Setenv("TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER", "No")

featureArray := strings.Split(constants.FeatureContextCommand, ".")
err = config.SetFeature(featureArray[1], featureArray[2], "true")
Expand All @@ -423,6 +429,7 @@ func TestUpgradePlugin(t *testing.T) {
defer func() {
os.Unsetenv("TANZU_CONFIG")
os.Unsetenv("TANZU_CONFIG_NEXT_GEN")
os.Unsetenv("TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER")
os.RemoveAll(tkgConfigFile.Name())
os.RemoveAll(tkgConfigFileNG.Name())
}()
Expand Down
15 changes: 14 additions & 1 deletion pkg/command/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,18 @@ func NewRootCmd() (*cobra.Command, error) {
SilenceUsage: true,
// Flag parsing must be deactivated because the root plugin won't know about all flags.
DisableFlagParsing: true,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if cmd.Name() != cobra.ShellCompRequestCmd && cmd.Name() != completionCmd.Name() {
// Configure CEIP setting but not if we are doing shell completion stuff.
// The shell completion setup is not interactive, so it should not trigger
// the ceip prompt.
if err := cliconfig.ConfigureCEIPOptIn(); err != nil {
return err
}
}
return nil
},
}

uFunc := cli.NewMainUsage().UsageFunc()
rootCmd.SetUsageFunc(uFunc)

Expand All @@ -49,6 +59,9 @@ func NewRootCmd() (*cobra.Command, error) {
completionCmd,
configCmd,
genAllDocsCmd,
// Note(TODO:prkalle): The below ceip-participation command(experimental) added may be removed in the next release,
// If we decide to fold this functionality into existing 'tanzu telemetry' plugin
newCEIPParticipationCmd(),
)

// If the context and target feature is enabled, add the corresponding commands under root.
Expand Down
2 changes: 2 additions & 0 deletions pkg/command/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ func TestEnvVarsSet(t *testing.T) {
defer os.RemoveAll(configFile.Name())
configFileNG, _ := os.CreateTemp("", "config_ng")
os.Setenv("TANZU_CONFIG_NEXT_GEN", configFileNG.Name())
os.Setenv("TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER", "No")
defer os.RemoveAll(configFileNG.Name())

// Setup default feature flags since we have created new config files
Expand Down Expand Up @@ -353,6 +354,7 @@ func TestEnvVarsSet(t *testing.T) {
// Cleanup
os.Unsetenv("TANZU_CONFIG")
os.Unsetenv("TANZU_CONFIG_NEXT_GEN")
os.Unsetenv("TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER")
os.Unsetenv(envVarName)
}

Expand Down
Loading