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

feat: add dev preview capability #668

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 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
23 changes: 12 additions & 11 deletions internal/config/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,18 @@ type IConfig interface {

// Config is a type which describes the properties which can be in the config
type Config struct {
AccessToken string `json:"access_token,omitempty" doc:"Bearer access token."`
RefreshToken string `json:"refresh_token,omitempty" doc:"Offline or refresh token."`
MasAuthURL string `json:"mas_auth_url,omitempty"`
MasAccessToken string `json:"mas_access_token,omitempty"`
MasRefreshToken string `json:"mas_refresh_token,omitempty"`
Services ServiceConfigMap `json:"services,omitempty"`
APIUrl string `json:"api_url,omitempty" doc:"URL of the API gateway. The value can be the complete URL or an alias. The valid aliases are 'production', 'staging' and 'integration'."`
AuthURL string `json:"auth_url,omitempty" doc:"URL of the authentication server"`
ClientID string `json:"client_id,omitempty" doc:"OpenID client identifier."`
Insecure bool `json:"insecure,omitempty" doc:"Enables insecure communication with the server. This disables verification of TLS certificates and host names."`
Scopes []string `json:"scopes,omitempty" doc:"OpenID scope. If this option is used it will replace completely the default scopes. Can be repeated multiple times to specify multiple scopes."`
AccessToken string `json:"access_token,omitempty" doc:"Bearer access token."`
RefreshToken string `json:"refresh_token,omitempty" doc:"Offline or refresh token."`
MasAuthURL string `json:"mas_auth_url,omitempty"`
MasAccessToken string `json:"mas_access_token,omitempty"`
MasRefreshToken string `json:"mas_refresh_token,omitempty"`
Services ServiceConfigMap `json:"services,omitempty"`
APIUrl string `json:"api_url,omitempty" doc:"URL of the API gateway. The value can be the complete URL or an alias. The valid aliases are 'production', 'staging' and 'integration'."`
AuthURL string `json:"auth_url,omitempty" doc:"URL of the authentication server"`
ClientID string `json:"client_id,omitempty" doc:"OpenID client identifier."`
Insecure bool `json:"insecure,omitempty" doc:"Enables insecure communication with the server. This disables verification of TLS certificates and host names."`
Scopes []string `json:"scopes,omitempty" doc:"OpenID scope. If this option is used it will replace completely the default scopes. Can be repeated multiple times to specify multiple scopes."`
DevPreviewEnabled bool `json:"dev_preview_enabled,omitempty" doc:"Enables Developer preview commands"`
}

// ServiceConfigMap is a map of configs for the application services
Expand Down
32 changes: 31 additions & 1 deletion pkg/arguments/arguments.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,43 @@
// This file contains functions that add common arguments to the command line

package arguments

import (
"strings"

"github.com/redhat-developer/app-services-cli/internal/config"
"github.com/redhat-developer/app-services-cli/pkg/cmd/debug"
"github.com/redhat-developer/app-services-cli/pkg/cmd/factory"
"github.com/spf13/pflag"
)

// AddDebugFlag adds the '--debug' flag to the given set of command line flags
func AddDebugFlag(fs *pflag.FlagSet) {
debug.AddFlag(fs)
}

// Enables dev preview in config
func EnableDevPreview(f *factory.Factory, enablement *string) (*config.Config, error) {
if *enablement == "" {
// Flag not present no action needed.
return nil, nil
}

logger, err := f.Logger()
if err != nil {
logger.Info("Cannot enable dev preview")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will do i18n as last step on the feature branch. Ignore non externalized strings for now

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That will fail because the logger is not created.

return nil, err
}
config, err := f.Config.Load()
if err != nil {
logger.Info("Cannot enable dev preview")
return nil, err
}

config.DevPreviewEnabled = strings.ToLower(*enablement) == "true" || *enablement == "yes" || *enablement == "y"
err = f.Config.Save(config)
if err != nil {
logger.Info("Cannot enable dev preview")
return nil, err
}
return config, err
}
21 changes: 11 additions & 10 deletions pkg/cmd/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,22 @@
package registry

import (
"github.com/spf13/cobra"

"github.com/redhat-developer/app-services-cli/pkg/cmd/factory"
"github.com/redhat-developer/app-services-cli/pkg/cmd/kafka/create"
"github.com/redhat-developer/app-services-cli/pkg/cmd/kafka/delete"
"github.com/redhat-developer/app-services-cli/pkg/cmd/kafka/describe"
"github.com/redhat-developer/app-services-cli/pkg/cmd/kafka/list"
"github.com/redhat-developer/app-services-cli/pkg/cmd/kafka/use"
"github.com/redhat-developer/app-services-cli/pkg/cmd/registry/create"
"github.com/redhat-developer/app-services-cli/pkg/cmd/registry/delete"
"github.com/redhat-developer/app-services-cli/pkg/cmd/registry/describe"
"github.com/redhat-developer/app-services-cli/pkg/cmd/registry/list"
"github.com/redhat-developer/app-services-cli/pkg/cmd/registry/use"
"github.com/redhat-developer/app-services-cli/pkg/profile"
"github.com/spf13/cobra"
)

func NewServiceRegistryCommand(f *factory.Factory) *cobra.Command {
cmd := &cobra.Command{
Use: "registry",
Short: "Service Registry commands",
Args: cobra.MinimumNArgs(1),
Use: "registry",
Annotations: profile.DevPreviewAnnotation(),
Short: profile.DevPreviewLabel() + "Service Registry commands",
Args: cobra.MinimumNArgs(1),
}

// add sub-commands
Expand Down
12 changes: 10 additions & 2 deletions pkg/cmd/root/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"flag"

"github.com/redhat-developer/app-services-cli/pkg/cmd/registry"
"github.com/redhat-developer/app-services-cli/pkg/profile"

"github.com/redhat-developer/app-services-cli/internal/build"
"github.com/redhat-developer/app-services-cli/pkg/cmd/login"
Expand Down Expand Up @@ -36,7 +37,6 @@ func NewRootCommand(f *factory.Factory, version string) *cobra.Command {
cmd.Version = version

cmd.SetVersionTemplate(f.Localizer.MustLocalize("version.cmd.outputText", localize.NewEntry("Version", build.Version)))

pflag.CommandLine.AddGoFlagSet(flag.CommandLine)

fs := cmd.PersistentFlags()
Expand All @@ -46,17 +46,25 @@ func NewRootCommand(f *factory.Factory, version string) *cobra.Command {
var help bool
fs.BoolVarP(&help, "help", "h", false, f.Localizer.MustLocalize("root.cmd.flag.help.description"))

devpreview := ""
cmd.Flags().StringVar(&devpreview, "devpreview", "", f.Localizer.MustLocalize("root.cmd.flag.devpreview.description"))
_, _ = profile.EnableDevPreview(f, &devpreview)

// Child commands
cmd.AddCommand(login.NewLoginCmd(f))
cmd.AddCommand(logout.NewLogoutCommand(f))
cmd.AddCommand(kafka.NewKafkaCommand(f))
cmd.AddCommand(registry.NewServiceRegistryCommand(f))
cmd.AddCommand(serviceaccount.NewServiceAccountCommand(f))
cmd.AddCommand(cluster.NewClusterCommand(f))
cmd.AddCommand(status.NewStatusCommand(f))
cmd.AddCommand(completion.NewCompletionCommand(f))
cmd.AddCommand(whoami.NewWhoAmICmd(f))
cmd.AddCommand(cliversion.NewVersionCmd(f))

// Dev preview commands
if profile.DevPreviewEnabled(f) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have investigated using custom help message template based on the annotations, however that will require pulling some large parts of the internal cobra functions etc. so decided to simplify it by listing those commands bellow. This will be mostly seen by us so there is no big deal with it.

cmd.AddCommand(registry.NewServiceRegistryCommand(f))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❯ ./rhoas --devpreview=yes registry
Error: unknown command "registry" for "rhoas"

How do I get this to work?

}

return cmd
}
5 changes: 4 additions & 1 deletion pkg/localize/locales/en/cmd/root.en.en.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@ $ rhoas cluster connect
'''

[root.cmd.flag.help.description]
one = 'Show help for a command'
one = 'Show help for a command'

[root.cmd.flag.devpreview.description]
one = 'Enable commands that are available under early developer preview. Use --devpreview=yes'
64 changes: 64 additions & 0 deletions pkg/profile/profile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// This file contains functions that help to manage visibility of early stage commands
package profile

import (
"strings"

"github.com/redhat-developer/app-services-cli/internal/config"
"github.com/redhat-developer/app-services-cli/pkg/cmd/factory"
"github.com/redhat-developer/app-services-cli/pkg/color"
)

// Visual element displayed in help
func DevPreviewLabel() string {
return color.Info("[Preview] ")
}

// Annotation used in templates and tools like documentation generation
func DevPreviewAnnotation() map[string]string {
return map[string]string{"channel": "preview"}
}

// Check if preview is enabled
func DevPreviewEnabled(f *factory.Factory) bool {
logger, err := f.Logger()
if err != nil {
logger.Info("Cannot determine status of dev preview. ", err)
return false
}
config, err := f.Config.Load()
if err != nil {
logger.Info("Cannot determine status of dev preview. ", err)
return false
}

return config.DevPreviewEnabled
}

// Enable dev preview
func EnableDevPreview(f *factory.Factory, enablement *string) (*config.Config, error) {
if *enablement == "" {
// Flag not present no action needed.
return nil, nil
}

logger, err := f.Logger()
if err != nil {
logger.Info("Cannot enable dev preview. ", err)
return nil, err
}
config, err := f.Config.Load()
if err != nil {
logger.Info("Cannot enable dev preview.", err)
return nil, err
}

config.DevPreviewEnabled = strings.ToLower(*enablement) == "true" || *enablement == "yes" || *enablement == "y"
err = f.Config.Save(config)
if err != nil {
logger.Info("Cannot enable dev preview. ", err)
return nil, err
}
logger.Info("Successfully changed visibility of devpreview commands")
return config, err
}
65 changes: 65 additions & 0 deletions pkg/profile/profile_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package profile

import (
"testing"

"github.com/redhat-developer/app-services-cli/pkg/cmd/factory"
)

func TestEnableDevPreviewConfig(t *testing.T) {
testVal := ""
config, err := EnableDevPreview(factory.New("dev", nil), &testVal)
if config != nil {
t.Errorf("TestEnableDevPreviewConfig config = %v, want %v", config, nil)
}
if err != nil {
t.Errorf("TestEnableDevPreviewConfig error = %v, want %v", err, nil)
}

testVal = "giberish"
config, err = EnableDevPreview(factory.New("dev", nil), &testVal)
if config.DevPreviewEnabled == true {
t.Errorf("TestEnableDevPreviewConfig() config.DevPreviewEnabled = %v, want %v", config.DevPreviewEnabled, false)
}
if err != nil {
t.Errorf("TestEnableDevPreviewConfig error = %v, want %v", err, nil)
}

testVal = "true"
config, err = EnableDevPreview(factory.New("dev", nil), &testVal)
if config.DevPreviewEnabled != true {
t.Errorf("TestEnableDevPreviewConfig config.DevPreviewEnabled = %v, want %v", config.DevPreviewEnabled, true)
}
if err != nil {
t.Errorf("TestEnableDevPreviewConfig error = %v, want %v", err, nil)
}

testVal = "yes"
config, err = EnableDevPreview(factory.New("dev", nil), &testVal)
if config.DevPreviewEnabled != true {
t.Errorf("TestEnableDevPreviewConfig config.DevPreviewEnabled = %v, want %v", config.DevPreviewEnabled, true)
}
if err != nil {
t.Errorf("TestEnableDevPreviewConfig error = %v, want %v", err, nil)
}
}

func TestDevPreviewEnabled(t *testing.T) {
f := factory.New("dev", nil)
testVal := "false"
config, _ := EnableDevPreview(f, &testVal)
t.Log("Ess", config)
enabled := DevPreviewEnabled(f)

if enabled {
t.Errorf("TestEnableDevPreviewConfig enabled = %v, want %v", enabled, false)
}

testVal = "true"
_, _ = EnableDevPreview(f, &testVal)

enabled = DevPreviewEnabled(f)
if !enabled {
t.Errorf("TestEnableDevPreviewConfig enabled = %v, want %v", enabled, true)
}
}