mirror of https://github.com/coder/coder.git
cli prints license warnings (#3716)
* cli prints license warnings Signed-off-by: Spike Curtis <spike@coder.com> * Satisfy the linter Signed-off-by: Spike Curtis <spike@coder.com> Signed-off-by: Spike Curtis <spike@coder.com>
This commit is contained in:
parent
62f686c003
commit
779c446a6e
77
cli/root.go
77
cli/root.go
|
@ -35,18 +35,20 @@ var (
|
|||
)
|
||||
|
||||
const (
|
||||
varURL = "url"
|
||||
varToken = "token"
|
||||
varAgentToken = "agent-token"
|
||||
varAgentURL = "agent-url"
|
||||
varGlobalConfig = "global-config"
|
||||
varNoOpen = "no-open"
|
||||
varNoVersionCheck = "no-version-warning"
|
||||
varForceTty = "force-tty"
|
||||
varVerbose = "verbose"
|
||||
notLoggedInMessage = "You are not logged in. Try logging in using 'coder login <url>'."
|
||||
varURL = "url"
|
||||
varToken = "token"
|
||||
varAgentToken = "agent-token"
|
||||
varAgentURL = "agent-url"
|
||||
varGlobalConfig = "global-config"
|
||||
varNoOpen = "no-open"
|
||||
varNoVersionCheck = "no-version-warning"
|
||||
varNoFeatureWarning = "no-feature-warning"
|
||||
varForceTty = "force-tty"
|
||||
varVerbose = "verbose"
|
||||
notLoggedInMessage = "You are not logged in. Try logging in using 'coder login <url>'."
|
||||
|
||||
envNoVersionCheck = "CODER_NO_VERSION_WARNING"
|
||||
envNoVersionCheck = "CODER_NO_VERSION_WARNING"
|
||||
envNoFeatureWarning = "CODER_NO_FEATURE_WARNING"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -103,29 +105,25 @@ func Root(subcommands []*cobra.Command) *cobra.Command {
|
|||
Long: `Coder — A tool for provisioning self-hosted development environments.
|
||||
`,
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
err := func() error {
|
||||
if cliflag.IsSetBool(cmd, varNoVersionCheck) {
|
||||
return nil
|
||||
}
|
||||
if cliflag.IsSetBool(cmd, varNoVersionCheck) &&
|
||||
cliflag.IsSetBool(cmd, varNoFeatureWarning) {
|
||||
return
|
||||
}
|
||||
|
||||
// Login handles checking the versions itself since it
|
||||
// has a handle to an unauthenticated client.
|
||||
// Server is skipped for obvious reasons.
|
||||
if cmd.Name() == "login" || cmd.Name() == "server" || cmd.Name() == "gitssh" {
|
||||
return nil
|
||||
}
|
||||
// Login handles checking the versions itself since it
|
||||
// has a handle to an unauthenticated client.
|
||||
// Server is skipped for obvious reasons.
|
||||
if cmd.Name() == "login" || cmd.Name() == "server" || cmd.Name() == "gitssh" {
|
||||
return
|
||||
}
|
||||
|
||||
client, err := CreateClient(cmd)
|
||||
// If the client is unauthenticated we can ignore the check.
|
||||
// The child commands should handle an unauthenticated client.
|
||||
if xerrors.Is(err, errUnauthenticated) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return xerrors.Errorf("create client: %w", err)
|
||||
}
|
||||
return checkVersions(cmd, client)
|
||||
}()
|
||||
client, err := CreateClient(cmd)
|
||||
// If we are unable to create a client, presumably the subcommand will fail as well
|
||||
// so we can bail out here.
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = checkVersions(cmd, client)
|
||||
if err != nil {
|
||||
// Just log the error here. We never want to fail a command
|
||||
// due to a pre-run.
|
||||
|
@ -133,6 +131,7 @@ func Root(subcommands []*cobra.Command) *cobra.Command {
|
|||
cliui.Styles.Warn.Render("check versions error: %s"), err)
|
||||
_, _ = fmt.Fprintln(cmd.ErrOrStderr())
|
||||
}
|
||||
checkWarnings(cmd, client)
|
||||
},
|
||||
Example: formatExamples(
|
||||
example{
|
||||
|
@ -152,6 +151,7 @@ func Root(subcommands []*cobra.Command) *cobra.Command {
|
|||
|
||||
cmd.PersistentFlags().String(varURL, "", "Specify the URL to your deployment.")
|
||||
cliflag.Bool(cmd.PersistentFlags(), varNoVersionCheck, "", envNoVersionCheck, false, "Suppress warning when client and server versions do not match.")
|
||||
cliflag.Bool(cmd.PersistentFlags(), varNoFeatureWarning, "", envNoFeatureWarning, false, "Suppress warnings about unlicensed features.")
|
||||
cliflag.String(cmd.PersistentFlags(), varToken, "", envSessionToken, "", fmt.Sprintf("Specify an authentication token. For security reasons setting %s is preferred.", envSessionToken))
|
||||
cliflag.String(cmd.PersistentFlags(), varAgentToken, "", "CODER_AGENT_TOKEN", "", "Specify an agent authentication token.")
|
||||
_ = cmd.PersistentFlags().MarkHidden(varAgentToken)
|
||||
|
@ -493,3 +493,16 @@ download the server version with: 'curl -L https://coder.com/install.sh | sh -s
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkWarnings(cmd *cobra.Command, client *codersdk.Client) {
|
||||
if cliflag.IsSetBool(cmd, varNoFeatureWarning) {
|
||||
return
|
||||
}
|
||||
entitlements, err := client.Entitlements(cmd.Context())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, w := range entitlements.Warnings {
|
||||
_, _ = fmt.Fprintln(cmd.ErrOrStderr(), cliui.Styles.Warn.Render(w))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
|
||||
"github.com/coder/coder/cli/clitest"
|
||||
"github.com/coder/coder/coderd/coderdtest"
|
||||
"github.com/coder/coder/coderd/httpapi"
|
||||
"github.com/coder/coder/codersdk"
|
||||
"github.com/coder/coder/enterprise/cli"
|
||||
"github.com/coder/coder/enterprise/coderd"
|
||||
|
@ -28,6 +29,7 @@ import (
|
|||
)
|
||||
|
||||
const fakeLicenseJWT = "test.jwt.sig"
|
||||
const testWarning = "This is a test warning"
|
||||
|
||||
func TestLicensesAddFake(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
@ -179,6 +181,8 @@ func TestLicensesListReal(t *testing.T) {
|
|||
"licenses", "list")
|
||||
stdout := new(bytes.Buffer)
|
||||
cmd.SetOut(stdout)
|
||||
stderr := new(bytes.Buffer)
|
||||
cmd.SetErr(stderr)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
@ -188,6 +192,7 @@ func TestLicensesListReal(t *testing.T) {
|
|||
}()
|
||||
require.NoError(t, <-errC)
|
||||
assert.Equal(t, "[]\n", stdout.String())
|
||||
assert.Contains(t, testWarning, stderr.String())
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -260,6 +265,7 @@ func newFakeLicenseAPI(t *testing.T) http.Handler {
|
|||
r.Get("/api/v2/licenses", a.licenses)
|
||||
r.Get("/api/v2/buildinfo", a.noop)
|
||||
r.Delete("/api/v2/licenses/{id}", a.deleteLicense)
|
||||
r.Get("/api/v2/entitlements", a.entitlements)
|
||||
return r
|
||||
}
|
||||
|
||||
|
@ -330,3 +336,18 @@ func (s *fakeLicenseAPI) deleteLicense(rw http.ResponseWriter, r *http.Request)
|
|||
assert.Equal(s.t, "55", chi.URLParam(r, "id"))
|
||||
rw.WriteHeader(200)
|
||||
}
|
||||
|
||||
func (*fakeLicenseAPI) entitlements(rw http.ResponseWriter, _ *http.Request) {
|
||||
features := make(map[string]codersdk.Feature)
|
||||
for _, f := range codersdk.FeatureNames {
|
||||
features[f] = codersdk.Feature{
|
||||
Entitlement: codersdk.EntitlementEntitled,
|
||||
Enabled: true,
|
||||
}
|
||||
}
|
||||
httpapi.Write(rw, http.StatusOK, codersdk.Entitlements{
|
||||
Features: features,
|
||||
Warnings: []string{testWarning},
|
||||
HasLicense: true,
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue