From 60fe7bbba0ea45e961c0e3ecdf416fab4f039c1e Mon Sep 17 00:00:00 2001 From: Ping-Lin Chang Date: Fri, 27 Oct 2023 22:38:02 +0100 Subject: [PATCH] feat(auth): config oauth2 default login during build time --- .goreleaser.yml | 4 +++ internal/config/config_type.go | 1 + internal/config/from_file.go | 18 +++----------- internal/config/stub.go | 4 +++ internal/oauth2/auth_code_flow.go | 16 +++++++++--- pkg/cmd/api/api.go | 2 +- pkg/cmd/auth/login/login.go | 41 ++++++++++++++++++++++--------- pkg/cmd/local/deploy.go | 4 +-- script/build.go | 4 +++ 9 files changed, 61 insertions(+), 33 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 4b42803..49423d6 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -21,6 +21,10 @@ builds: - -s -w - -X github.com/instill-ai/cli/internal/build.Version={{ .Version }} - -X github.com/instill-ai/cli/internal/build.Date={{ time "2006-01-02" }} + - -X github.com/instill-ai/cli/internal/oauth2.apiHostname="api.instill.tech" + - -X github.com/instill-ai/cli/internal/oauth2.oauth2Hostname="auth.instill.tech" + - -X github.com/instill-ai/cli/internal/oauth2.oauth2Audience="https://api.instill.tech" + - -X github.com/instill-ai/cli/internal/oauth2.oauth2Issuer="https://auth.instill.tech/" - -X github.com/instill-ai/cli/internal/oauth2.clientID={{ .Env.INSTILL_OAUTH_CLIENT_ID }} - -X github.com/instill-ai/cli/internal/oauth2.clientSecret={{ .Env.INSTILL_OAUTH_CLIENT_SECRET }} - -X main.updaterEnabled=instill-ai/cli diff --git a/internal/config/config_type.go b/internal/config/config_type.go index 7c9133f..2f59720 100644 --- a/internal/config/config_type.go +++ b/internal/config/config_type.go @@ -14,6 +14,7 @@ type Config interface { UnsetHost(string) error Hosts() ([]string, error) HostsTyped() ([]HostConfigTyped, error) + HostEntries() ([]*HostConfig, error) DefaultHostname() string CheckWriteable(string, string) error Write() error diff --git a/internal/config/from_file.go b/internal/config/from_file.go index 1ceb6f1..1acda8a 100644 --- a/internal/config/from_file.go +++ b/internal/config/from_file.go @@ -103,21 +103,11 @@ func (c *fileConfig) UnsetHost(hostname string) error { cm := ConfigMap{hostsEntry.ValueNode} cm.RemoveEntry(hostname) - _, err = c.hostEntries() - if strings.Contains(err.Error(), "could not find any host configurations") { - // no hosts, fallback to the default hostname - defaultHost := instance.FallbackHostname() - err = c.Set("", "default_hostname", defaultHost) - if err != nil { - return err - } - } - return nil } func (c *fileConfig) ConfigForHost(hostname string) (*HostConfig, error) { - hosts, err := c.hostEntries() + hosts, err := c.HostEntries() if err != nil { return nil, err } @@ -167,7 +157,7 @@ func (c *fileConfig) Write() error { return WriteConfigFile(HostsConfigFile(), yamlNormalize(hostsBytes)) } -func (c *fileConfig) hostEntries() ([]*HostConfig, error) { +func (c *fileConfig) HostEntries() ([]*HostConfig, error) { entry, err := c.FindEntry("hosts") if err != nil { return []*HostConfig{}, nil @@ -184,7 +174,7 @@ func (c *fileConfig) hostEntries() ([]*HostConfig, error) { // Hosts returns a list of all known hostnames configured in hosts.yml // TODO replace with HostsTyped func (c *fileConfig) Hosts() ([]string, error) { - entries, err := c.hostEntries() + entries, err := c.HostEntries() if err != nil { return nil, err } @@ -203,7 +193,7 @@ func (c *fileConfig) Hosts() ([]string, error) { // Every call re-reads the config file. func (c *fileConfig) HostsTyped() ([]HostConfigTyped, error) { var ret []HostConfigTyped - hosts, err := c.hostEntries() + hosts, err := c.HostEntries() if err != nil { return nil, err } diff --git a/internal/config/stub.go b/internal/config/stub.go index 83a8fed..bf539e3 100644 --- a/internal/config/stub.go +++ b/internal/config/stub.go @@ -36,6 +36,10 @@ func (c ConfigStub) Hosts() ([]string, error) { return nil, nil } +func (c ConfigStub) HostEntries() ([]*HostConfig, error) { + return nil, nil +} + func (c ConfigStub) UnsetHost(hostname string) error { return nil } diff --git a/internal/oauth2/auth_code_flow.go b/internal/oauth2/auth_code_flow.go index cdd8a31..3d6e80f 100644 --- a/internal/oauth2/auth_code_flow.go +++ b/internal/oauth2/auth_code_flow.go @@ -26,6 +26,14 @@ import ( ) var ( + // apiHostname is the default API hostname for the Instill Cloud server. + apiHostname = "" + // The OAuth2 hostname for the Instill Cloud server. + oauth2Hostname = "" + // The OAuth2 audience for the Instill Cloud server. + oauth2Audience = "" + // The OAuth2 issuer for the Instill Cloud server. + oauth2Issuer = "" // The "Instill CLI" OAuth app (build-time default to api.instill.tech) clientID = "" // This value is safe to be embedded in version control (build-time default to api.instill.tech) @@ -36,11 +44,11 @@ var ( func HostConfigInstillCloud() *config.HostConfigTyped { host := config.DefaultHostConfig() - host.APIHostname = "api.instill.tech" + host.APIHostname = apiHostname host.IsDefault = true - host.Oauth2Hostname = "auth.instill.tech" - host.Oauth2Audience = "https://api.instill.tech" - host.Oauth2Issuer = "https://auth.instill.tech/" + host.Oauth2Hostname = oauth2Hostname + host.Oauth2Audience = oauth2Audience + host.Oauth2Issuer = oauth2Issuer host.Oauth2ClientID = clientID host.Oauth2ClientSecret = clientSecret return &host diff --git a/pkg/cmd/api/api.go b/pkg/cmd/api/api.go index 6056433..08c9c34 100644 --- a/pkg/cmd/api/api.go +++ b/pkg/cmd/api/api.go @@ -97,7 +97,7 @@ func NewCmdAPI(f *cmdutil.Factory, runF func(*ApiOptions) error) *cobra.Command $ inst api model/v1alpha/models # get user profile - $ inst api base/v1alpha/users/me + $ inst api core/v1alpha/users/me # add parameters to a GET request $ inst api model/v1alpha/models?visibility=public diff --git a/pkg/cmd/auth/login/login.go b/pkg/cmd/auth/login/login.go index adcd408..857b65f 100644 --- a/pkg/cmd/auth/login/login.go +++ b/pkg/cmd/auth/login/login.go @@ -92,19 +92,36 @@ func loginRun(f *cmdutil.Factory, opts *LoginOptions) error { return err } } else { - hostname := opts.Hostname - hosts, err := cfg.HostsTyped() - if err != nil { + // in case the hosts.yml is empty + cfg, _ := opts.Config() + if hosts, err := cfg.HostEntries(); err != nil { return err - } - for _, h := range hosts { - if h.APIHostname == hostname { - host = &h - break + } else if len(hosts) == 0 { + // no hosts, fallback to the default hostname + host = oauth2.HostConfigInstillCloud() + err = cfg.SaveTyped(host) + if err != nil { + return err + } + err = cfg.Set("", "default_hostname", host.APIHostname) + if err != nil { + return err + } + } else { + hostname := opts.Hostname + hosts, err := cfg.HostsTyped() + if err != nil { + return err + } + for _, h := range hosts { + if h.APIHostname == hostname { + host = &h + break + } + } + if host == nil { + return fmt.Errorf("ERROR: instance '%s' does not exists", hostname) } - } - if host == nil { - return fmt.Errorf("ERROR: instance '%s' does not exists", hostname) } } @@ -171,7 +188,7 @@ type localLoginRequest struct { // loginLocal handles dedicated auth flow for Instill Core. func loginLocal(transport http.RoundTripper, hostname, password string) (string, error) { - url := instance.GetProtocol(hostname) + "base/v1alpha/auth/login" + url := instance.GetProtocol(hostname) + "core/v1alpha/auth/login" data := &localLoginRequest{ Name: local.DefUsername, Pass: password, diff --git a/pkg/cmd/local/deploy.go b/pkg/cmd/local/deploy.go index ecc8f10..754a202 100644 --- a/pkg/cmd/local/deploy.go +++ b/pkg/cmd/local/deploy.go @@ -78,8 +78,8 @@ func NewDeployCmd(f *cmdutil.Factory, runF func(*DeployOptions) error) *cobra.Co cmd.Flags().BoolVarP(&opts.Force, "force", "f", false, "Force to deploy a new local Instill Core instance") cmd.Flags().BoolVarP(&opts.Upgrade, "upgrade", "u", false, "Upgrade Instill Core instance to the latest release version") + cmd.Flags().BoolVarP(&opts.Build, "build", "b", false, "Deploy an Instill Core instance and build latest release version") cmd.Flags().BoolVarP(&opts.Latest, "latest", "l", false, "Deploy an Instill Core instance with the latest version (unstable)") - cmd.Flags().BoolVarP(&opts.Build, "build", "b", false, "Deploy an Instill Core instance and build the images at the local") cmd.MarkFlagsMutuallyExclusive("force", "upgrade") cmd.MarkFlagsMutuallyExclusive("upgrade", "latest") @@ -242,7 +242,7 @@ func runDeploy(opts *DeployOptions) error { if opts.Latest { p(opts.IO, "Spin up latest Instill Core...") - if out, err := execCmd(opts.Exec, "bash", "-c", fmt.Sprintf("make latest BUILD=%s", strconv.FormatBool(opts.Build))); err != nil { + if out, err := execCmd(opts.Exec, "bash", "-c", "make latest"); err != nil { return fmt.Errorf("ERROR: Instill Core spin-up failed, %w\n%s", err, out) } } else { diff --git a/script/build.go b/script/build.go index 6524aea..db41b07 100644 --- a/script/build.go +++ b/script/build.go @@ -53,6 +53,10 @@ var tasks = map[string]func(string) error{ ldflags = fmt.Sprintf("-X github.com/instill-ai/cli/internal/build.Version=%s %s", version(), ldflags) ldflags = fmt.Sprintf("-X github.com/instill-ai/cli/internal/build.Date=%s %s", date(), ldflags) if oauthSecret := os.Getenv("INSTILL_OAUTH_CLIENT_SECRET"); oauthSecret != "" { + ldflags = fmt.Sprintf("-X github.com/instill-ai/cli/internal/oauth2.apiHostname=%s %s", os.Getenv("INSTILL_OAUTH_API_HOSTNAME"), ldflags) + ldflags = fmt.Sprintf("-X github.com/instill-ai/cli/internal/oauth2.oauth2Hostname=%s %s", os.Getenv("INSTILL_OAUTH_OAUTH_HOSTNAME"), ldflags) + ldflags = fmt.Sprintf("-X github.com/instill-ai/cli/internal/oauth2.oauth2Audience=%s %s", os.Getenv("INSTILL_OAUTH_OAUTH_AUDIENCE"), ldflags) + ldflags = fmt.Sprintf("-X github.com/instill-ai/cli/internal/oauth2.oauth2Issuer=%s %s", os.Getenv("INSTILL_OAUTH_OAUTH_ISSUER"), ldflags) ldflags = fmt.Sprintf("-X github.com/instill-ai/cli/internal/oauth2.clientID=%s %s", os.Getenv("INSTILL_OAUTH_CLIENT_ID"), ldflags) ldflags = fmt.Sprintf("-X github.com/instill-ai/cli/internal/oauth2.clientSecret=%s %s", oauthSecret, ldflags) }