refactor: grpc client to separate cloud and sync API

This commit is contained in:
abhisek 2024-10-07 23:04:18 +05:30
parent c0e915cfaa
commit d016c63174
No known key found for this signature in database
GPG Key ID: CB92A4990C02A88F
4 changed files with 67 additions and 14 deletions

33
auth.go
View File

@ -2,6 +2,7 @@ package main
import ( import (
"errors" "errors"
"fmt"
"os" "os"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
@ -15,20 +16,24 @@ import (
var ( var (
authInsightApiBaseUrl string authInsightApiBaseUrl string
authControlPlaneApiBaseUrl string authControlPlaneApiBaseUrl string
authSyncApiBaseUrl string
authCommunity bool authCommunity bool
authTenantDomain string
) )
func newAuthCommand() *cobra.Command { func newAuthCommand() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "auth", Use: "auth",
Short: "[Deprecated] Use cloud command", Short: "Configure vet authentication",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
return errors.New("a valid sub-command is required") return errors.New("a valid sub-command is required")
}, },
} }
cmd.PersistentFlags().StringVarP(&authControlPlaneApiBaseUrl, "control-plane", "", cmd.PersistentFlags().StringVarP(&authControlPlaneApiBaseUrl, "control-plane", "",
auth.DefaultControlTowerUrl(), "Base URL of Control Plane API") auth.ControlTowerUrl(), "Base URL of Control Plane API")
cmd.PersistentFlags().StringVarP(&authSyncApiBaseUrl, "sync", "", auth.SyncApiUrl(),
"Base URL of Sync API")
cmd.AddCommand(configureAuthCommand()) cmd.AddCommand(configureAuthCommand())
cmd.AddCommand(verifyAuthCommand()) cmd.AddCommand(verifyAuthCommand())
@ -55,11 +60,31 @@ func configureAuthCommand() *cobra.Command {
logger.Fatalf("Failed to setup auth: %v", err) logger.Fatalf("Failed to setup auth: %v", err)
} }
if auth.TenantDomain() != "" && auth.TenantDomain() != authTenantDomain {
ui.PrintWarning(fmt.Sprintf("Tenant domain mismatch. Existing: %s, New: %s, continue? ",
auth.TenantDomain(), authTenantDomain))
var confirm bool
err = survey.AskOne(&survey.Confirm{
Message: "Do you want to continue?",
}, &confirm)
if err != nil {
logger.Fatalf("Failed to setup auth: %v", err)
}
if !confirm {
return nil
}
}
err = auth.Configure(auth.Config{ err = auth.Configure(auth.Config{
ApiUrl: authInsightApiBaseUrl, ApiUrl: authInsightApiBaseUrl,
ApiKey: string(key), ApiKey: string(key),
ControlPlaneApiUrl: authControlPlaneApiBaseUrl, ControlPlaneApiUrl: authControlPlaneApiBaseUrl,
SyncApiUrl: authSyncApiBaseUrl,
Community: authCommunity, Community: authCommunity,
TenantDomain: authTenantDomain,
}) })
if err != nil { if err != nil {
@ -71,11 +96,15 @@ func configureAuthCommand() *cobra.Command {
}, },
} }
cmd.Flags().StringVarP(&authTenantDomain, "tenant-domain", "", "",
"Tenant domain for SafeDep Cloud")
cmd.Flags().StringVarP(&authInsightApiBaseUrl, "api", "", auth.DefaultApiUrl(), cmd.Flags().StringVarP(&authInsightApiBaseUrl, "api", "", auth.DefaultApiUrl(),
"Base URL of Insights API") "Base URL of Insights API")
cmd.Flags().BoolVarP(&authCommunity, "community", "", false, cmd.Flags().BoolVarP(&authCommunity, "community", "", false,
"Use community API endpoint for Insights") "Use community API endpoint for Insights")
_ = cmd.MarkFlagRequired("tenant-domain")
return cmd return cmd
} }

View File

@ -17,10 +17,10 @@ const (
defaultApiUrl = "https://api.safedep.io/insights/v1" defaultApiUrl = "https://api.safedep.io/insights/v1"
defaultCommunityApiUrl = "https://api.safedep.io/insights-community/v1" defaultCommunityApiUrl = "https://api.safedep.io/insights-community/v1"
defaultSyncApiUrl = "https://api.safedep.io/sync/v1"
// gRPC service base URL. // gRPC service base URL.
defaultControlPlaneApiUrl = "https://api.safedep.io" defaultSyncApiUrl = "https://api.safedep.io"
defaultControlPlaneApiUrl = "https://cloud.safedep.io"
homeRelativeConfigPath = ".safedep/vet-auth.yml" homeRelativeConfigPath = ".safedep/vet-auth.yml"
) )
@ -29,8 +29,9 @@ type Config struct {
ApiUrl string `yaml:"api_url"` ApiUrl string `yaml:"api_url"`
ApiKey string `yaml:"api_key"` ApiKey string `yaml:"api_key"`
Community bool `yaml:"community"` Community bool `yaml:"community"`
ControlPlaneApiUrl string `yaml:"cp_api_url"` ControlPlaneApiUrl string `yaml:"control_api_url"`
SyncApiUrl string `yaml:"sync_api_url"` SyncApiUrl string `yaml:"sync_api_url"`
TenantDomain string `yaml:"tenant_domain"`
} }
// Global config to be used during runtime // Global config to be used during runtime
@ -53,7 +54,7 @@ func DefaultCommunityApiUrl() string {
return defaultCommunityApiUrl return defaultCommunityApiUrl
} }
func DefaultSyncApiUrl() string { func SyncApiUrl() string {
if (globalConfig != nil) && (globalConfig.SyncApiUrl != "") { if (globalConfig != nil) && (globalConfig.SyncApiUrl != "") {
return globalConfig.SyncApiUrl return globalConfig.SyncApiUrl
} }
@ -61,7 +62,7 @@ func DefaultSyncApiUrl() string {
return defaultSyncApiUrl return defaultSyncApiUrl
} }
func DefaultControlTowerUrl() string { func ControlTowerUrl() string {
if (globalConfig != nil) && (globalConfig.ControlPlaneApiUrl != "") { if (globalConfig != nil) && (globalConfig.ControlPlaneApiUrl != "") {
return globalConfig.ControlPlaneApiUrl return globalConfig.ControlPlaneApiUrl
} }
@ -69,6 +70,14 @@ func DefaultControlTowerUrl() string {
return defaultControlPlaneApiUrl return defaultControlPlaneApiUrl
} }
func TenantDomain() string {
if globalConfig != nil {
return globalConfig.TenantDomain
}
return ""
}
func ApiUrl() string { func ApiUrl() string {
if url, ok := os.LookupEnv(apiUrlEnvKey); ok { if url, ok := os.LookupEnv(apiUrlEnvKey); ok {
return url return url

View File

@ -15,7 +15,15 @@ import (
// Create a gRPC client connection for the control plane // Create a gRPC client connection for the control plane
// based on available configuration // based on available configuration
func ControlPlaneClientConnection(name string) (*grpc.ClientConn, error) { func ControlPlaneClientConnection(name string) (*grpc.ClientConn, error) {
parsedUrl, err := url.Parse(DefaultControlTowerUrl()) return cloudClientConnection(name, ControlTowerUrl())
}
func SyncClientConnection(name string) (*grpc.ClientConn, error) {
return cloudClientConnection(name, SyncApiUrl())
}
func cloudClientConnection(name, loc string) (*grpc.ClientConn, error) {
parsedUrl, err := url.Parse(loc)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -27,13 +35,20 @@ func ControlPlaneClientConnection(name string) (*grpc.ClientConn, error) {
logger.Debugf("ControlTower host: %s, port: %s", host, port) logger.Debugf("ControlTower host: %s, port: %s", host, port)
// For local development, we use the mock user. vetTenantId := TenantDomain()
vetTenantId := os.Getenv("VET_CONTROL_TOWER_TENANT_ID") tenantIdOverride := os.Getenv("VET_CONTROL_TOWER_TENANT_ID")
vetTenantMockUser := os.Getenv("VET_CONTROL_TOWER_MOCK_USER")
if tenantIdOverride != "" {
vetTenantId = tenantIdOverride
}
headers := http.Header{} headers := http.Header{}
headers.Set("x-tenant-id", vetTenantId) headers.Set("x-tenant-id", vetTenantId)
vetTenantMockUser := os.Getenv("VET_CONTROL_TOWER_MOCK_USER")
if vetTenantMockUser != "" {
headers.Set("x-mock-user", vetTenantMockUser) headers.Set("x-mock-user", vetTenantMockUser)
}
client, err := drygrpc.GrpcClient(name, host, port, client, err := drygrpc.GrpcClient(name, host, port,
ApiKey(), headers, []grpc.DialOption{}) ApiKey(), headers, []grpc.DialOption{})

View File

@ -179,7 +179,7 @@ func listParsersCommand() *cobra.Command {
func startScan() { func startScan() {
if !disableAuthVerifyBeforeScan { if !disableAuthVerifyBeforeScan {
err := auth.Verify(&auth.VerifyConfig{ err := auth.Verify(&auth.VerifyConfig{
ControlPlaneApiUrl: auth.DefaultControlTowerUrl(), ControlPlaneApiUrl: auth.ControlTowerUrl(),
}) })
// We will fallback to community mode by default to provide // We will fallback to community mode by default to provide
@ -396,7 +396,7 @@ func internalStartScan() error {
} }
if syncReport { if syncReport {
clientConn, err := auth.ControlPlaneClientConnection("vet-sync") clientConn, err := auth.SyncClientConnection("vet-sync")
if err != nil { if err != nil {
return err return err
} }