8000 feat(cdsctl,api): cdsctl admin database list / delete (#3842) · ovh/cds@eeb1665 · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Commit eeb1665

Browse files
authored
feat(cdsctl,api): cdsctl admin database list / delete (#3842)
* feat(cdsctl,api): cdsctl admin database list / delete Signed-off-by: Yvonnick Esnault <yvonnick.esnault@corp.ovh.com>
1 parent f1a668c commit eeb1665

File tree

17 files changed

+290
-133
lines changed
  • sdk
  • tests
  • 17 files changed

    +290
    -133
    lines changed

    cli/cdsctl/admin_database.go

    Lines changed: 27 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -14,6 +14,8 @@ var adminDatabaseCmd = cli.Command{
    1414
    func adminDatabase() *cobra.Command {
    1515
    return cli.NewCommand(adminDatabaseCmd, nil, []*cobra.Command{
    1616
    cli.NewCommand(adminDatabaseUnlockCmd, adminDatabaseUnlockFunc, nil),
    17+
    cli.NewCommand(adminDatabaseDeleteMigrationCmd, adminDatabaseDeleteFunc, nil),
    18+
    cli.NewListCommand(adminDatabaseMigrationsList, adminDatabaseMigrationsListFunc, nil),
    1719
    })
    1820
    }
    1921

    @@ -28,3 +30,28 @@ var adminDatabaseUnlockCmd = cli.Command{
    2830
    func adminDatabaseUnlockFunc(v cli.Values) error {
    2931
    return client.AdminDatabaseMigrationUnlock(v.GetString("id"))
    3032
    }
    33+
    34+
    var adminDatabaseDeleteMigrationCmd = cli.Command{
    35+
    Name: "delete",
    36+
    Short: "Delete a database migration from table gorp_migration (use with caution)",
    37+
    Args: []cli.Arg{
    38+
    {Name: "id"},
    39+
    },
    40+
    }
    41+
    42+
    func adminDatabaseDeleteFunc(v cli.Values) error {
    43+
    return client.AdminDatabaseMigrationDelete(v.GetString("id"))
    44< 6D4E code class="diff-text syntax-highlighted-line addition">+
    }
    45+
    46+
    var adminDatabaseMigrationsList = cli.Command{
    47+
    Name: "list",
    48+
    Short: "List all CDS DB migrations",
    49+
    }
    50+
    51+
    func adminDatabaseMigrationsListFunc(_ cli.Values) (cli.ListResult, error) {
    52+
    migrations, err := client.AdminDatabaseMigrationsList()
    53+
    if err != nil {
    54+
    return nil, err
    55+
    }
    56+
    return cli.AsListResult(migrations), nil
    57+
    }

    cli/cdsctl/admin_migrations.go

    Lines changed: 6 additions & 0 deletions
    13
    Original file line numberDiff line numberDiff line change
    @@ -12,6 +12,12 @@ import (
    1212
    var adminMigrationsCmd = cli.Command{
    13
    Name: "migration",
    1414
    Short: "Manage CDS Migrations",
    15+
    Long: `Theses commands manage CDS Migration and DO NOT concern database migrations.
    16+
    17+
    A CDS Migration is an internal routine. This helps manage a complex data migration with code included
    18+
    in CDS Engine. It's totally transpartent to CDS Users & Administrators - but these commands can help
    19+
    CDS Administrators and core CDS Developers to debug something if needed.
    20+
    `,
    1521
    }
    1622

    1723
    func adminMigrations() *cobra.Command {

    engine/api/api_routes.go

    Lines changed: 3 additions & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -47,7 +47,9 @@ func (api *API) InitRouter() {
    4747
    r.Handle("/admin/cds/migration", r.GET(api.getAdminMigrationsHandler, NeedAdmin(true)))
    4848
    r.Handle("/admin/cds/migration/{id}/cancel", r.POST(api.postAdminMigrationCancelHandler, NeedAdmin(true)))
    4949
    r.Handle("/admin/cds/migration/{id}/todo", r.POST(api.postAdminMigrationTodoHandler, NeedAdmin(true)))
    50-
    r.Handle("/admin/database/migration/unlock/{id}", r.POST(api.postMigrationUnlockedHandler, NeedAdmin(true)))
    50+
    r.Handle("/admin/database/migration/delete/{id}", r.DELETE(api.deleteDatabaseMigrationHandler, NeedAdmin(true)))
    51+
    r.Handle("/admin/database/migration/unlock/{id}", r.POST(api.postDatabaseMigrationUnlockedHandler, NeedAdmin(true)))
    52+
    r.Handle("/admin/database/migration", r.GET(api.getDatabaseMigrationHandler, NeedAdmin(true)))
    5153
    r.Handle("/admin/debug", r.GET(api.getProfileIndexHandler, Auth(false)))
    5254
    r.Handle("/admin/debug/trace", r.POST(api.getTraceHandler, NeedAdmin(true)), r.GET(api.getTraceHandler, NeedAdmin(true)))
    5355
    r.Handle("/admin/debug/cpu", r.POST(api.getCPUProfileHandler, NeedAdmin(true)), r.GET(api.getCPUProfileHandler, NeedAdmin(true)))

    engine/api/database.go

    Lines changed: 24 additions & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -11,7 +11,20 @@ import (
    1111
    "github.com/ovh/cds/sdk"
    1212
    )
    1313

    14-
    func (api *API) postMigrationUnlockedHandler() service.Handler {
    14+
    func (api *API) deleteDatabaseMigrationHandler() service.Handler {
    15+
    return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
    16+
    vars := mux.Vars(r)
    17+
    id := vars["id"]
    18+
    19+
    if len(id) == 0 {
    20+
    return sdk.NewErrorFrom(sdk.ErrWrongRequest, "Id is mandatory. Check id from table gorp_migrations")
    21+
    }
    22+
    23+
    return dbmigrate.DeleteMigrate(api.mustDB().Db, id)
    24+
    }
    25+
    }
    26+
    27+
    func (api *API) postDatabaseMigrationUnlockedHandler() service.Handler {
    1528
    return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
    1629
    vars := mux.Vars(r)
    1730
    id := vars["id"]
    @@ -23,3 +36,13 @@ func (api *API) postMigrationUnlockedHandler() service.Handler {
    2336
    return dbmigrate.UnlockMigrate(api.mustDB().Db, id)
    2437
    }
    2538
    }
    39+
    40+
    func (api *API) getDatabaseMigrationHandler() service.Handler {
    41+
    return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
    42+
    a, err := dbmigrate.List(api.mustDB().Db)
    43+
    if err != nil {
    44+
    return sdk.WrapError(err, "Cannot load database migration list %d", err)
    45+
    }
    46+
    return service.WriteJSON(w, a, http.StatusOK)
    47+
    }
    48+
    }

    engine/api/database/database.go

    Lines changed: 54 additions & 54 deletions
    Original file line numberDiff line numberDiff line change
    @@ -15,40 +15,40 @@ import (
    1515

    1616
    // DBConnectionFactory is a database connection factory on postgres with gorp
    1717
    type DBConnectionFactory struct {
    18-
    dbDriver string
    19-
    dbRole string
    20-
    dbUser string
    21-
    dbPassword string
    22-
    dbName string
    23-
    dbHost string
    24-
    dbPort int
    25-
    dbSSLMode string
    26-
    dbTimeout int
    27-
    dbConnectTimeout int
    28-
    dbMaxConn int
    29-
    db *sql.DB
    18+
    DBDriver string
    19+
    DBRole string
    20+
    DBUser string
    21+
    DBPassword string
    22+
    DBName string
    23+
    DBHost string
    24+
    DBPort int
    25+
    DBSSLMode string
    26+
    DBTimeout int
    27+
    DBConnectTimeout int
    28+
    DBMaxConn int
    29+
    Database *sql.DB
    3030
    mutex *sync.Mutex
    3131
    }
    3232

    3333
    // DB returns the current sql.DB object
    3434
    func (f *DBConnectionFactory) DB() *sql.DB {
    35-
    if f.db == nil {
    36-
    if f.dbName == "" {
    35+
    if f.Database == nil {
    36+
    if f.DBName == "" {
    3737
    return nil
    3838
    }
    39-
    newF, err := Init(f.dbUser, f.dbRole, f.dbPassword, f.dbName, f.dbHost, f.dbPort, f.dbSSLMode, f.dbConnectTimeout, f.dbTimeout, f.dbMaxConn)
    39+
    newF, err := Init(f.DBUser, f.DBRole, f.DBPassword, f.DBName, f.DBHost, f.DBPort, f.DBSSLMode, f.DBConnectTimeout, f.DBTimeout, f.DBMaxConn)
    4040
    if err != nil {
    4141
    log.Error("Database> cannot init db connection : %s", err)
    4242
    return nil
    4343
    }
    4444
    *f = *newF
    4545
    }
    46-
    if err := f.db.Ping(); err != nil {
    46+
    if err := f.Database.Ping(); err != nil {
    4747
    log.Error("Database> cannot ping db : %s", err)
    48-
    f.db = nil
    48+
    f.Database = nil
    4949
    return nil
    5050
    }
    51-
    return f.db
    51+
    return f.Database
    5252
    }
    5353

    5454
    // GetDBMap returns a gorp.DbMap pointer
    @@ -58,76 +58,76 @@ func (f *DBConnectionFactory) GetDBMap() *gorp.DbMap {
    5858

    5959
    //Set is for tetsing purpose, we need to set manually the connection
    6060
    func (f *DBConnectionFactory) Set(d *sql.DB) {
    61-
    f.db = d
    61+
    f.Database = d
    6262
    }
    6363

    6464
    // Init initialize sql.DB object by checking environment variables and connecting to database
    6565
    func Init(user, role, password, name, host string, port int, sslmode string, connectTimeout, timeout, maxconn int) (*DBConnectionFactory, error) {
    6666
    f := &DBConnectionFactory{
    67-
    dbDriver: "postgres",
    68-
    dbRole: role,
    69-
    dbUser: user,
    70-
    dbPassword: password,
    71-
    dbName: name,
    72-
    dbHost: host,
    73-
    dbPort: port,
    74-
    dbSSLMode: sslmode,
    75-
    dbTimeout: timeout,
    76-
    dbConnectTimeout: connectTimeout,
    77-
    dbMaxConn: maxconn,
    67+
    DBDriver: "postgres",
    68+
    DBRole: role,
    69+
    DBUser: user,
    70+
    DBPassword: password,
    71+
    DBName: name,
    72+
    DBHost: host,
    73+
    DBPort: port,
    74+
    DBSSLMode: sslmode,
    75+
    DBTimeout: timeout,
    76+
    DBConnectTimeout: connectTimeout,
    77+
    DBMaxConn: maxconn,
    7878
    mutex: &sync.Mutex{},
    7979
    }
    8080

    8181
    f.mutex.Lock()
    8282
    defer f.mutex.Unlock()
    8383

    8484
    // Try to close before reinit
    85-
    if f.db != nil {
    86-
    if err := f.db.Close(); err != nil {
    85+
    if f.Database != nil {
    86+
    if err := f.Database.Close(); err != nil {
    8787
    log.Error("Cannot close connection to DB : %s", err)
    8888
    }
    8989
    }
    9090

    9191
    var err error
    9292

    93-
    if f.dbUser == "" ||
    94-
    f.dbPassword == "" ||
    95-
    f.dbName == "" ||
    96-
    f.dbHost == "" ||
    97-
    f.dbPort == 0 {
    93+
    if f.DBUser == "" ||
    94+
    f.DBPassword == "" ||
    95+
    f.DBName == "" ||
    96+
    f.DBHost == "" ||
    97+
    f.DBPort == 0 {
    9898
    return nil, fmt.Errorf("Missing database infos")
    9999
    }
    100100

    101-
    if f.dbTimeout < 200 || f.dbTimeout > 30000 {
    102-
    f.dbTimeout = 3000
    101+
    if f.DBTimeout < 200 || f.DBTimeout > 30000 {
    102+
    f.DBTimeout = 3000
    103103
    }
    104104

    105-
    if f.dbConnectTimeout <= 0 {
    106-
    f.dbConnectTimeout = 10
    105+
    if f.DBConnectTimeout <= 0 {
    106+
    f.DBConnectTimeout = 10
    107107
    }
    108108

    109109
    // connect_timeout in seconds
    110110
    // statement_timeout in milliseconds
    111111
    dsn := f.dsn()
    112-
    f.db, err = sql.Open(f.dbDriver, dsn)
    112+
    f.Database, err = sql.Open(f.DBDriver, dsn)
    113113
    if err != nil {
    114-
    f.db = nil
    114+
    f.Database = nil
    115115
    log.Error("cannot open database: %s", err)
    116116
    return nil, err
    117117
    }
    118118

    119-
    if err = f.db.Ping(); err != nil {
    120-
    f.db = nil
    119+
    if err = f.Database.Ping(); err != nil {
    120+
    f.Database = nil
    121121
    return nil, err
    122122
    }
    123123

    124-
    f.db.SetMaxOpenConns(f.dbMaxConn)
    125-
    f.db.SetMaxIdleConns(int(f.dbMaxConn / 2))
    124+
    f.Database.SetMaxOpenConns(f.DBMaxConn)
    125+
    f.Database.SetMaxIdleConns(int(f.DBMaxConn / 2))
    126126

    127127
    // Set role if specified
    128128
    if role != "" {
    129129
    log.Debug("database> setting role %s on database", role)
    130-
    if _, err := f.db.Exec("SET ROLE '" + role + "'"); err != nil {
    130+
    if _, err := f.Database.Exec("SET ROLE '" + role + "'"); err != nil {
    131131
    log.Error("unable to set role %s on database: %s", role, err)
    132132
    return nil, sdk.WrapError(err, "unable to set role %s", role)
    133133
    }
    @@ -137,26 +137,26 @@ func Init(user, role, password, name, host string, port int, sslmode string, con
    137137
    }
    138138

    139139
    func (f *DBConnectionFactory) dsn() string {
    140-
    return fmt.Sprintf("user=%s password=%s dbname=%s host=%s port=%d sslmode=%s connect_timeout=%d statement_timeout=%d", f.dbUser, f.dbPassword, f.dbName, f.dbHost, f.dbPort, f.dbSSLMode, f.dbConnectTimeout, f.dbTimeout)
    140+
    return fmt.Sprintf("user=%s password=%s dbname=%s host=%s port=%d sslmode=%s connect_timeout=%d statement_timeout=%d", f.DBUser, f.DBPassword, f.DBName, f.DBHost, f.DBPort, f.DBSSLMode, f.DBConnectTimeout, f.DBTimeout)
    141141
    }
    142142

    143143
    // Status returns database driver and status in a printable string
    144144
    func (f *DBConnectionFactory) Status() sdk.MonitoringStatusLine {
    145-
    if f.db == nil {
    145+
    if f.Database == nil {
    146146
    return sdk.MonitoringStatusLine{Component: "Database Conns", Value: "No Connection", Status: sdk.MonitoringStatusAlert}
    147147
    }
    148148

    149-
    if err := f.db.Ping(); err != nil {
    149+
    if err := f.Database.Ping(); err != nil {
    150150
    return sdk.MonitoringStatusLine{Component: "Database Conns", Value: "No Ping", Status: sdk.MonitoringStatusAlert}
    151151
    }
    152152

    153-
    return sdk.MonitoringStatusLine{Component: "Database Conns", Value: fmt.Sprintf("%d", f.db.Stats().OpenConnections), Status: sdk.MonitoringStatusOK}
    153+
    return sdk.MonitoringStatusLine{Component: "Database Conns", Value: fmt.Sprintf("%d", f.Database.Stats().OpenConnections), Status: sdk.MonitoringStatusOK}
    154154
    }
    155155

    156156
    // Close closes the database, releasing any open resources.
    157157
    func (f *DBConnectionFactory) Close() error {
    158-
    if f.db != nil {
    159-
    return f.db.Close()
    158+
    if f.Database != nil {
    159+
    return f.Database.Close()
    160160
    }
    161161
    return nil
    162162
    }

    0 commit comments

    Comments
     (0)
    0