Skip to content

Commit

Permalink
Merge pull request #630 from iamkirkbater/refactor-config
Browse files Browse the repository at this point in the history
Initial refactor to prepare to move some packages to ocm-common
  • Loading branch information
ciaranRoche authored Aug 19, 2024
2 parents 5066ea0 + 2c66dc0 commit ac42b5c
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 126 deletions.
3 changes: 2 additions & 1 deletion cmd/ocm/login/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"time"

"github.com/openshift-online/ocm-cli/pkg/config"
"github.com/openshift-online/ocm-cli/pkg/ocm"
"github.com/openshift-online/ocm-cli/pkg/properties"
"github.com/openshift-online/ocm-cli/pkg/urls"
sdk "github.com/openshift-online/ocm-sdk-go"
Expand Down Expand Up @@ -329,7 +330,7 @@ func run(cmd *cobra.Command, argv []string) error {
cfg.Insecure = args.insecure

// Create a connection and get the token to verify that the crendentials are correct:
connection, err := cfg.Connection()
connection, err := ocm.NewConnection().Config(cfg).Build()
if err != nil {
return fmt.Errorf("Can't create connection: %v", err)
}
Expand Down
61 changes: 0 additions & 61 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,9 @@ import (
"path/filepath"
"time"

"github.com/golang/glog"
homedir "github.com/mitchellh/go-homedir"
sdk "github.com/openshift-online/ocm-sdk-go"
"github.com/openshift-online/ocm-sdk-go/authentication/securestore"

"github.com/openshift-online/ocm-cli/pkg/debug"
"github.com/openshift-online/ocm-cli/pkg/info"
"github.com/openshift-online/ocm-cli/pkg/properties"
)

Expand Down Expand Up @@ -265,63 +261,6 @@ func (c *Config) Disarm() {
c.User = ""
}

// Connection creates a connection using this configuration.
func (c *Config) Connection() (connection *sdk.Connection, err error) {
// Create the logger:
level := glog.Level(1)
if debug.Enabled() {
level = glog.Level(0)
}
logger, err := sdk.NewGlogLoggerBuilder().
DebugV(level).
InfoV(level).
WarnV(level).
Build()
if err != nil {
return
}

// Prepare the builder for the connection adding only the properties that have explicit
// values in the configuration, so that default values won't be overridden:
builder := sdk.NewConnectionBuilder()
builder.Logger(logger)
builder.Agent("OCM-CLI/" + info.Version)
if c.TokenURL != "" {
builder.TokenURL(c.TokenURL)
}
if c.ClientID != "" || c.ClientSecret != "" {
builder.Client(c.ClientID, c.ClientSecret)
}
if c.Scopes != nil {
builder.Scopes(c.Scopes...)
}
if c.URL != "" {
builder.URL(c.URL)
}
if c.User != "" || c.Password != "" {
builder.User(c.User, c.Password)
}
tokens := make([]string, 0, 2)
if c.AccessToken != "" {
tokens = append(tokens, c.AccessToken)
}
if c.RefreshToken != "" {
tokens = append(tokens, c.RefreshToken)
}
if len(tokens) > 0 {
builder.Tokens(tokens...)
}
builder.Insecure(c.Insecure)

// Create the connection:
connection, err = builder.Build()
if err != nil {
return
}

return
}

// IsKeyringManaged returns the keyring name and a boolean indicating if the config is managed by the keyring.
func IsKeyringManaged() (keyring string, ok bool) {
keyring = os.Getenv(properties.KeyringEnvKey)
Expand Down
180 changes: 180 additions & 0 deletions pkg/ocm/connection-builder/connection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/*
Copyright (c) 2020 Red Hat, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package connection

import (
"fmt"

"github.com/golang/glog"
sdk "github.com/openshift-online/ocm-sdk-go"
"github.com/openshift-online/ocm-sdk-go/logging"

"github.com/openshift-online/ocm-cli/pkg/config"
"github.com/openshift-online/ocm-cli/pkg/debug"
"github.com/openshift-online/ocm-cli/pkg/info"
)

// ConnectionBuilder contains the information and logic needed to build a connection to OCM. Don't
// create instances of this type directly; use the NewConnection function instead.
type ConnectionBuilder struct {
// cfg is the ocm config file loaded from disk or keychain
cfg *config.Config

// logger is a logging instance used by the ocm sdk
// defaults to a basic logger instance
logger logging.Logger

// api url override is provided to override the configuration file API url
// defaults to whatever is in the ocm config file
apiUrlOverride string

// agent is the UserAgent for a given CLI.
// defaults to OCM_CLI+version
agent string
}

// NewConnection creates a builder that can then be used to configure and build an OCM connection.
// Don't create instances of this type directly; use the NewConnection function instead.
func NewConnection() *ConnectionBuilder {
return &ConnectionBuilder{}
}

// Config sets the configuration that the connection will use to authenticate the user
func (b *ConnectionBuilder) Config(value *config.Config) *ConnectionBuilder {
b.cfg = value
return b
}

// Override the default logging implementation
func (b *ConnectionBuilder) WithLogger(logger logging.Logger) *ConnectionBuilder {
b.logger = logger
return b
}

// Override the default API URL
func (b *ConnectionBuilder) WithApiUrl(url string) *ConnectionBuilder {
b.apiUrlOverride = url
return b
}

// Override the default UserAgent String
func (b *ConnectionBuilder) AsAgent(agent string) *ConnectionBuilder {
b.agent = agent
return b
}

// Build uses the information stored in the builder to create a new OCM connection.
func (b *ConnectionBuilder) Build() (result *sdk.Connection, err error) {
if b.cfg == nil {
// Load the configuration file:
b.cfg, err = config.Load()
if err != nil {
return
}
if b.cfg == nil {
err = fmt.Errorf("Not logged in, run the 'login' command")
return
}
}

// Check that the configuration has credentials or tokens that haven't have expired:
armed, reason, err := b.cfg.Armed()
if err != nil {
return
}
if !armed {
err = fmt.Errorf("Not logged in, %s, run the 'login' command", reason)
return
}

builder := b.initConnectionBuilderFromConfig()

logger, err := b.getLogger()
if err != nil {
return
}
builder.Logger(logger)

agent := b.getAgent()
builder.Agent(agent)

if b.apiUrlOverride != "" {
builder.URL(b.apiUrlOverride)
}

// Create the connection:
return builder.Build()
}

func (b *ConnectionBuilder) initConnectionBuilderFromConfig() *sdk.ConnectionBuilder {
builder := sdk.NewConnectionBuilder()

// Prepare the builder for the connection adding only the properties that have explicit
// values in the configuration, so that default values won't be overridden:
if b.cfg.TokenURL != "" {
builder.TokenURL(b.cfg.TokenURL)
}
if b.cfg.ClientID != "" || b.cfg.ClientSecret != "" {
builder.Client(b.cfg.ClientID, b.cfg.ClientSecret)
}
if b.cfg.Scopes != nil {
builder.Scopes(b.cfg.Scopes...)
}
if b.cfg.User != "" || b.cfg.Password != "" {
builder.User(b.cfg.User, b.cfg.Password)
}
if b.cfg.URL != "" {
builder.URL(b.cfg.URL)
}
tokens := make([]string, 0, 2)
if b.cfg.AccessToken != "" {
tokens = append(tokens, b.cfg.AccessToken)
}
if b.cfg.RefreshToken != "" {
tokens = append(tokens, b.cfg.RefreshToken)
}
if len(tokens) > 0 {
builder.Tokens(tokens...)
}
builder.Insecure(b.cfg.Insecure)

return builder
}

// Returns the configured logger or a default if there is none configured
func (b *ConnectionBuilder) getLogger() (logging.Logger, error) {
if b.logger != nil {
return b.logger, nil
}

// Create a default logger:
level := glog.Level(1)
if debug.Enabled() {
level = glog.Level(0)
}

return sdk.NewGlogLoggerBuilder().
DebugV(level).
InfoV(level).
WarnV(level).
Build()
}

// Returns the configured agent or a default value if there is none configured
func (b *ConnectionBuilder) getAgent() string {
if b.agent != "" {
return b.agent
}
return "OCM-CLI/" + info.Version
}
71 changes: 7 additions & 64 deletions pkg/ocm/connection.go
Original file line number Diff line number Diff line change
@@ -1,84 +1,27 @@
/*
Copyright (c) 2020 Red Hat, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package ocm

import (
"fmt"
"os"

sdk "github.com/openshift-online/ocm-sdk-go"

"github.com/openshift-online/ocm-cli/pkg/config"
"github.com/openshift-online/ocm-cli/pkg/debug"
"github.com/openshift-online/ocm-cli/pkg/info"
conn "github.com/openshift-online/ocm-cli/pkg/ocm/connection-builder"
"github.com/openshift-online/ocm-cli/pkg/properties"
)

// ConnectionBuilder contains the information and logic needed to build a connection to OCM. Don't
// create instances of this type directly; use the NewConnection function instead.
type ConnectionBuilder struct {
cfg *config.Config
}

// NewConnection creates a builder that can then be used to configure and build an OCM connection.
// Don't create instances of this type directly; use the NewConnection function instead.
func NewConnection() *ConnectionBuilder {
return &ConnectionBuilder{}
}

// Config sets the configuration that the connection will use to authenticate the user
func (b *ConnectionBuilder) Config(value *config.Config) *ConnectionBuilder {
b.cfg = value
return b
}

// Build uses the information stored in the builder to create a new OCM connection.
func (b *ConnectionBuilder) Build() (result *sdk.Connection, err error) {
if b.cfg == nil {
// Load the configuration file:
b.cfg, err = config.Load()
if err != nil {
return
}
if b.cfg == nil {
err = fmt.Errorf("Not logged in, run the 'login' command")
return
}
}

// Check that the configuration has credentials or tokens that haven't have expired:
armed, reason, err := b.cfg.Armed()
if err != nil {
return
}
if !armed {
err = fmt.Errorf("Not logged in, %s, run the 'login' command", reason)
return
}
func NewConnection() *conn.ConnectionBuilder {
connection := conn.NewConnection()
connection = connection.AsAgent("OCM-CLI/" + info.Version)

// overwrite the config URL if the environment variable is set
if overrideUrl := os.Getenv(properties.URLEnvKey); overrideUrl != "" {
if debug.Enabled() {
fmt.Fprintf(os.Stderr, "INFO: %s is overridden via environment variable. This functionality is considered tech preview and may cause unexpected issues.\n", properties.URLEnvKey) //nolint:lll
fmt.Fprintf(os.Stderr, " If you experience issues while %s is set, unset the %s environment variable and attempt to log in directly to the desired OCM environment.\n\n", properties.URLEnvKey, properties.URLEnvKey) //nolint:lll
}
b.cfg.URL = overrideUrl
}

result, err = b.cfg.Connection()
if err != nil {
return
connection = connection.WithApiUrl(overrideUrl)
}

return
return connection
}

0 comments on commit ac42b5c

Please sign in to comment.