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

Initial refactor to prepare to move some packages to ocm-common #630

Merged
merged 3 commits into from
Aug 19, 2024
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
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
}
Loading