...

Source file src/edge-infra.dev/hack/tools/cicterminals/main.go

Documentation: edge-infra.dev/hack/tools/cicterminals

     1  /*
     2  ███████╗██╗░░░██╗███████╗██████╗░███████╗
     3  ██╔════╝╚██╗░██╔╝██╔════╝██╔══██╗██╔════╝
     4  █████╗░░░╚████╔╝░█████╗░░██║░░██║█████╗░░
     5  ██╔══╝░░░░╚██╔╝░░██╔══╝░░██║░░██║██╔══╝░░
     6  ███████╗░░░██║░░░███████╗██████╔╝███████╗
     7  ╚══════╝░░░╚═╝░░░╚══════╝╚═════╝░╚══════╝
     8  
     9  
    10  CLI program written to populate IENode resources within the cluster infra cluster
    11  for all existing terminals
    12  
    13  To run the program permissions to access the DB and PubSub are first required.
    14  This can be done by creating an ADC file for the bff-sa service account and setting
    15  the "GOOGLE_APPLICATION_CREDENTIALS" environment variable to the path of this file,
    16  e.g.
    17  
    18  gcloud auth application-default login --no-launch-browser --impersonate-service-account=bff-sa@ret-edge-dev0-foreman.iam.gserviceaccount.com
    19  export GOOGLE_APPLICATION_CREDENTIALS="~/.config/gcloud/application_default_credentials.json"
    20  
    21  The cli program can then be run like so:
    22  
    23  Using Database:
    24  cicterminals useDatabase --databaseHost=ret-edge-dev0-foreman:us-central1:edge-dev0 --databaseName=edge-dev0
    25  --databaseUser=bff-sa@ret-edge-dev0-foreman.iam --topLevelProjectID=ret-edge-dev0-foreman
    26  --chariotTopic=chariot-rides
    27  
    28  The following flags are required for the cli to run:
    29  databaseHost, databaseName, databaseUser, topLevelProjectID and chariotTopic
    30  The dryRun flag is an optional and defaults to false if not specified.
    31  launchdarklyKey is also an optional flag that defaults to using cluster id if not set.
    32  
    33  Once the script has finished running you should reset your gcloud login to your user account
    34  
    35  export GOOGLE_APPLICATION_CREDENTIALS=""
    36  gcloud config unset auth/impersonate_service_account
    37  gcloud auth application-default login --no-launch-browser
    38  */
    39  
    40  package main
    41  
    42  import (
    43  	"context"
    44  	"database/sql"
    45  	"errors"
    46  	"flag"
    47  	"fmt"
    48  	"os"
    49  
    50  	_ "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/dialers/postgres"
    51  	"github.com/peterbourgon/ff/v3/ffcli"
    52  
    53  	"edge-infra.dev/pkg/lib/gcp/cloudsql"
    54  
    55  	"edge-infra.dev/hack/tools/cicterminals/cicterminals"
    56  	usedatabase "edge-infra.dev/hack/tools/cicterminals/use-database"
    57  	"edge-infra.dev/pkg/edge/api/utils"
    58  	"edge-infra.dev/pkg/lib/cli/commands"
    59  )
    60  
    61  var (
    62  	fs                           = flag.NewFlagSet("cicterminals", flag.ExitOnError)
    63  	databaseHost                 = fs.String("databaseHost", os.Getenv("DatabaseHost"), "the host of the database to query")
    64  	databaseName                 = fs.String("databaseName", os.Getenv("DatabaseName"), "the name of the database to query")
    65  	databaseUser                 = fs.String("databaseUser", os.Getenv("DatabaseUser"), "the user of the specified database")
    66  	topLevelProjectID            = fs.String("topLevelProjectID", os.Getenv("TopLevelProjectID"), "the top level project id")
    67  	chariotTopic                 = fs.String("chariotTopic", os.Getenv("ChariotTopic"), "chariot pubsub topic")
    68  	launchdarklyKey              = fs.String("launchdarklyKey", os.Getenv("LD_KEY"), "launch darkly sdk key")
    69  	dryRun                       = fs.Bool("dryRun", false, "run cicterminals in dryRun mode and output results in stdout")
    70  	errDatabaseHostRequired      = errors.New("error database host is required")
    71  	errDatabaseNameRequired      = errors.New("error database name is required")
    72  	errDatabaseUserRequired      = errors.New("error database user is required")
    73  	errTopLevelProjectIDRequired = errors.New("error top level project id is required")
    74  	errChariotTopicRequired      = errors.New("error chariot topic is required")
    75  )
    76  
    77  func main() {
    78  	fmt.Println(os.Getenv("GOOGLE_APPLICATION_CREDENTIALS"))
    79  	err := fs.Parse(os.Args[2:])
    80  	if err != nil {
    81  		fmt.Fprintln(os.Stderr, "Flag parsing error ", err)
    82  		os.Exit(1)
    83  	}
    84  	if err := validateRequiredFlags(); err != nil {
    85  		fmt.Fprintln(os.Stderr, "Flag validation error ", err)
    86  		os.Exit(1)
    87  	}
    88  	if utils.IsNullOrEmpty(launchdarklyKey) {
    89  		os.Setenv("LD_KEY", *launchdarklyKey)
    90  	}
    91  	eyeConfig := cicterminals.New()
    92  	fmt.Println("")
    93  	fmt.Println(`
    94  			███████╗██╗░️░️░██╗███████╗██████╗░███████╗
    95  			██╔════╝╚██╗░██╔╝██╔════╝██╔══██╗██╔════╝
    96  		👁	█████╗░░░╚████╔╝░█████╗░░██║░░██║█████╗░░ ️️👁
    97  			██╔══╝░░░░╚██╔╝░░██╔══╝░░██║░░██║██╔══╝░░
    98  			███████╗░░░██║░░░███████╗██████╔╝███████╗
    99  			╚══════╝░░░╚═╝░░░╚══════╝╚═════╝░╚══════╝
   100  			`)
   101  	fmt.Println("")
   102  	fmt.Printf("Connecting to Database: %s with user %s\n", *databaseName, *databaseUser)
   103  	db, err := connectToDatabase()
   104  	if err != nil {
   105  		fmt.Fprintln(os.Stderr, "db connection error occurred ", err)
   106  		os.Exit(1)
   107  	}
   108  	eyeConfig.SetDBConnection(db)
   109  	useDatabase := eyeConfig.Exec("useDatabase", "cicterminals useDatabase", "populate the IENode CR in CIC using the SQL Database", *topLevelProjectID, *chariotTopic, *dryRun, usedatabase.CreateIENode, fs)
   110  	cmd := &ffcli.Command{
   111  		Name:       "cicterminals",
   112  		ShortUsage: "cicterminals --databaseHost=ret-edge-dev0-foreman:us-central1:edge-dev0 --databaseName=edge-dev0 --databaseUser=bff-sa@ret-edge-dev0-foreman.iam --topLevelProjectID=ret-edge-dev0-foreman --chariotTopic=chariot-rides",
   113  		ShortHelp:  "populate IENode CR for all terminals",
   114  		Subcommands: []*ffcli.Command{
   115  			useDatabase,
   116  			commands.Version(),
   117  		},
   118  	}
   119  	if err := cmd.ParseAndRun(context.Background(), os.Args[1:]); err != nil {
   120  		fmt.Fprintf(os.Stderr, "error: %v\n", err)
   121  		os.Exit(1)
   122  	}
   123  }
   124  
   125  func validateRequiredFlags() error {
   126  	if utils.IsNullOrEmpty(databaseHost) {
   127  		return errDatabaseHostRequired
   128  	}
   129  	if utils.IsNullOrEmpty(databaseName) {
   130  		return errDatabaseNameRequired
   131  	}
   132  	if utils.IsNullOrEmpty(databaseUser) {
   133  		return errDatabaseUserRequired
   134  	}
   135  	if utils.IsNullOrEmpty(topLevelProjectID) {
   136  		return errTopLevelProjectIDRequired
   137  	}
   138  	if utils.IsNullOrEmpty(chariotTopic) {
   139  		return errChariotTopicRequired
   140  	}
   141  	return nil
   142  }
   143  
   144  func connectToDatabase() (*sql.DB, error) {
   145  	return cloudsql.GCPPostgresConnection(*databaseHost).Username(*databaseUser).DBName(*databaseName).NewConnection()
   146  }
   147  

View as plain text