...

Source file src/edge-infra.dev/cmd/edge/edge-sql/main.go

Documentation: edge-infra.dev/cmd/edge/edge-sql

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"database/sql"
     6  	_ "embed"
     7  	"flag"
     8  	"fmt"
     9  	"os"
    10  
    11  	_ "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/dialers/postgres"
    12  	"github.com/golang-migrate/migrate/v4/database/postgres"
    13  	_ "github.com/golang-migrate/migrate/v4/source/file"
    14  	"github.com/google/uuid"
    15  	_ "github.com/jackc/pgx/v4/stdlib" // nolint:revive necessary for db driver
    16  
    17  	sqlMetrics "edge-infra.dev/pkg/edge/api/sql/metrics"
    18  	"edge-infra.dev/pkg/edge/api/sql/migrationmanager"
    19  	"edge-infra.dev/pkg/edge/api/sql/plugin"
    20  	"edge-infra.dev/pkg/edge/api/sql/utils"
    21  	"edge-infra.dev/pkg/lib/gcp/cloudsql"
    22  	"edge-infra.dev/pkg/lib/logging"
    23  	"edge-infra.dev/pkg/lib/runtime/manager"
    24  	"edge-infra.dev/pkg/lib/runtime/metrics"
    25  	"edge-infra.dev/pkg/sds/emergencyaccess/sql/plugin/emergencyaccess"
    26  )
    27  
    28  var (
    29  	//go:embed config.yaml
    30  	configFile    []byte
    31  	currentConfig *plugin.Config
    32  )
    33  
    34  // Sqlconfig represents fields needed to establish a database connection.
    35  type Sqlconfig struct {
    36  	Host     string
    37  	User     string
    38  	DbName   string
    39  	Password string
    40  	Port     string
    41  }
    42  
    43  // newSQLConfig return a new Sqlconfig connection struct.
    44  func newSQLConfig() *Sqlconfig {
    45  	return &Sqlconfig{}
    46  }
    47  
    48  func init() {
    49  	var err error
    50  	currentConfig, err = plugin.InitializeWithConfig(configFile)
    51  	if err != nil {
    52  		fmt.Printf(utils.Logfmt, utils.SevError, err)
    53  		panic(err)
    54  	}
    55  }
    56  
    57  func main() {
    58  	log := logging.NewLogger().WithName("edge env sql")
    59  	log.Info("edge env sql migration started")
    60  
    61  	ctx, cancel := context.WithCancel(context.Background())
    62  	defer cancel()
    63  
    64  	sqlConfig := newSQLConfig()
    65  	topLevelProjectID := ""
    66  
    67  	flag.StringVar(&sqlConfig.Host, "dbHost", os.Getenv("SQL_CONNECTION_NAME"), "SQL Connection Host")
    68  	flag.StringVar(&sqlConfig.User, "dbUser", os.Getenv("SQL_USER"), "SQL Connection Username")
    69  	flag.StringVar(&sqlConfig.Password, "dbPassword", os.Getenv("SQL_PASSWORD"), "SQL Connection Password")
    70  	flag.StringVar(&sqlConfig.DbName, "dbName", os.Getenv("SQL_DB_NAME"), "SQL Connection Database Name")
    71  	flag.StringVar(&sqlConfig.Port, "port", os.Getenv("SQL_PORT"), "Port to connect on")
    72  	flag.StringVar(&topLevelProjectID, "topLevelProjectID", os.Getenv("TOP_LEVEL_PROJECT_ID"), "project id for foreman cluster")
    73  
    74  	db, err := sqlConfig.createSQLDBConnection()
    75  	if err != nil {
    76  		fmt.Printf(utils.Logfmt, utils.SevError, err)
    77  		panic(err)
    78  	}
    79  	driver, err := postgres.WithInstance(db, &postgres.Config{})
    80  	if err != nil {
    81  		fmt.Printf(utils.Logfmt, utils.SevError, err)
    82  		panic(err)
    83  	}
    84  
    85  	infraClusters := utils.Clusters{
    86  		&utils.Cluster{
    87  			EdgeID:    uuid.NewString(),
    88  			Name:      "foreman0",
    89  			ProjectID: topLevelProjectID, //todo get from configmap
    90  		},
    91  		&utils.Cluster{
    92  			EdgeID:    uuid.NewString(),
    93  			Name:      "banner-infra0",
    94  			ProjectID: topLevelProjectID, //todo get from configmap
    95  		},
    96  	}
    97  	currentConfig.Data = append(currentConfig.Data, plugin.Seed{
    98  		Name:     "seed-infra-clusters.tmpl",
    99  		Priority: 3,
   100  		Data:     infraClusters,
   101  	})
   102  
   103  	perms := utils.Permissions{
   104  		{
   105  			User:  fmt.Sprintf("edge-bsl@%s.iam", topLevelProjectID),
   106  			Role:  "ALL",
   107  			Table: "tenants",
   108  		},
   109  	}
   110  	currentConfig.Data = append(currentConfig.Data, plugin.Seed{
   111  		Name:     "seed-role.tmpl",
   112  		Priority: 4,
   113  		Data:     perms,
   114  	})
   115  
   116  	eaData, err := emergencyaccess.GetEASeedData(log, topLevelProjectID)
   117  	if err != nil {
   118  		// Log the error but continue as normal, no emergencyaccess data will be
   119  		// loaded (as long as eaData is empty)
   120  		log.Error(err, "Error getting EA Seed Data")
   121  	}
   122  	currentConfig.Data = append(currentConfig.Data, eaData...)
   123  
   124  	m := sqlMetrics.NewMetrics()
   125  	m.InitMetrics()
   126  
   127  	mgr, err := manager.New(manager.Options{
   128  		MetricsBindAddress: metrics.DefaultBindAddress,
   129  	})
   130  	if err != nil {
   131  		log.Error(err, "failed to initialize manager")
   132  	}
   133  
   134  	migrationMgr := migrationmanager.New(currentConfig, driver, log, db, m, cancel)
   135  	if err != nil {
   136  		log.Error(err, "failed to create a edgeSQL ops")
   137  		os.Exit(1)
   138  	}
   139  
   140  	if err := mgr.Add(migrationMgr); err != nil {
   141  		log.Error(err, "failed to add edgeSQL ops")
   142  		os.Exit(1)
   143  	}
   144  
   145  	if err := mgr.Start(ctx); err != nil {
   146  		log.Error(err, "failed to start mngr")
   147  		os.Exit(1)
   148  	}
   149  }
   150  
   151  // createSQLDBConnection creates a db connection.
   152  func (s *Sqlconfig) createSQLDBConnection() (*sql.DB, error) {
   153  	if s.Host == "localhost" {
   154  		db, err := sql.Open("pgx", fmt.Sprintf(
   155  			"host=%s port=%s user=%s password=%s dbname=%s",
   156  			s.Host, s.Port, s.User, s.Password, s.DbName),
   157  		)
   158  		if err != nil {
   159  			return nil, err
   160  		}
   161  		return db, nil
   162  	}
   163  	conn := cloudsql.GCPPostgresConnection(s.Host).
   164  		DBName(s.DbName).
   165  		Username(s.User)
   166  	if s.Password != "" {
   167  		conn.Password(s.Password)
   168  	}
   169  	return conn.NewConnection()
   170  }
   171  

View as plain text