Skip to content

Commit

Permalink
Change the behaviour on TimescaleDB metadata update fail
Browse files Browse the repository at this point in the history
Metadata update may fail because of lack of permissions
to read and write to the installation_metadata or
telemetry_metadata table. This shouldn't cause Outflux to
abort and fail.
  • Loading branch information
Blagoj Atanasovski authored and atanasovskib committed Jul 5, 2019
1 parent 7798b58 commit 46594b9
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 13 deletions.
37 changes: 37 additions & 0 deletions internal/schemamanagement/ts/table_creator_i_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,40 @@ func TestUpdateMetadata(t *testing.T) {
t.Fatalf("update time not proper, expected to be > than %v", timeBeforeUpdate)
}
}

func TestMetadataTableNameNoPermissions(t *testing.T) {
db := "test_update_metadata_2"
if err := testutils.DeleteTimescaleDb(db); err != nil {
t.Fatalf("could not prepare db: %v", err)
}
if err := testutils.CreateTimescaleDb(db); err != nil {
t.Fatalf("could not prepare db: %v", err)
}
defer testutils.DeleteTimescaleDb(db)
if err := testutils.CreateNonAdminInTS("dumb", "dumber"); err != nil {
t.Fatalf("could not prepare db: %v", err)
}

explorer := &defaultTableFinder{}
dbConnAdmin, err := testutils.OpenTSConn(db)
if err != nil {
t.Fatal(err)
}
dbConnAdmin.Exec(createTimescaleExtensionQuery)
dbConnAdmin.Close()

dbConn, err := testutils.OpenTsConnWithUser(db, "dumb", "dumber")
if err != nil {
t.Fatal(err)
}
defer dbConn.Close()
metadataTable, err := explorer.metadataTableName(dbConn)
if err != nil {
t.Fatal("unexpected err: ", err)
}

creator := defaultTableCreator{}
if creator.UpdateMetadata(dbConn, metadataTable) == nil {
t.Fatal("unexpected lack of error")
}
}
20 changes: 14 additions & 6 deletions internal/schemamanagement/ts/ts_schema_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ func (sm *TSSchemaManager) PrepareDataSet(dataSet *idrf.DataSet, strategy schema
return preparationError
}

return sm.updateMetadata()
sm.updateMetadata()
return nil
}

func (sm *TSSchemaManager) validateOnly(dataSet *idrf.DataSet, tableExists bool) error {
Expand Down Expand Up @@ -178,15 +179,22 @@ func (sm *TSSchemaManager) validatePartitioning(dataSet *idrf.DataSet) error {
return nil
}

func (sm *TSSchemaManager) updateMetadata() error {
func (sm *TSSchemaManager) updateMetadata() {
metadataTableName, err := sm.explorer.metadataTableName(sm.dbConn)
if err != nil {
return fmt.Errorf("could not check existance of installation metadata table. %v", err)
log.Println("could not check for the existence of the timescale metadata table")
log.Println("reason: " + err.Error())
return
}

if metadataTableName == "" {
log.Println("Installation metadata table doesn't exist in existing TimescaleDB version")
return nil
log.Println("Installation metadata table doesn't exist in this TimescaleDB version")
return
}

return sm.creator.UpdateMetadata(sm.dbConn, metadataTableName)
err = sm.creator.UpdateMetadata(sm.dbConn, metadataTableName)
if err != nil {
log.Println("could not update TimescaleDB metadata")
log.Println("reason:" + err.Error())
}
}
11 changes: 6 additions & 5 deletions internal/schemamanagement/ts/ts_schema_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,6 @@ func TestPrepareDataSetFails(t *testing.T) {
args: prepareArgs{DataSet: dataSet, Strategy: schemaconfig.ValidateOnly},
explorer: notPartitionedProperly(existingColumns),
desc: "validate only, compatible, is hypertable, partitioned by another column",
}, {
args: prepareArgs{DataSet: dataSet, Strategy: schemaconfig.ValidateOnly},
explorer: properMock(existingColumns),
creator: errorOnMetadataUpdate(existingColumns),
desc: "validate only, compatible, is hyper, partitioned properly, error on updating metadata",
},
}

Expand Down Expand Up @@ -164,6 +159,12 @@ func TestPrepareOk(t *testing.T) {
creator: okOnTableCreate(),
desc: "validate not called if need to create",
},
{
args: prepareArgs{DataSet: dataSet, Strategy: schemaconfig.ValidateOnly},
explorer: properMock(existingColumns),
creator: errorOnMetadataUpdate(existingColumns),
desc: "error on updating metadata",
},
}

for _, testC := range testCases {
Expand Down
25 changes: 23 additions & 2 deletions internal/testutils/server_preparation.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,35 @@ func CreateTimescaleSchema(db, schema string) error {
return err
}

// OpenTSConn opens a connection to a TimescaleDB
// OpenTSConn opens a connection to a TimescaleDB with the default (super admin) user/pass
func OpenTSConn(db string) (*pgx.Conn, error) {
connString := fmt.Sprintf(TsConnStringTemplate, db)
connConfig, _ := pgx.ParseConnectionString(connString)
log.Printf("opening ts conn to '%s' with: %s", db, connString)
log.Printf("opening ts conn to '%s' with:\n%s", db, connString)
return pgx.Connect(connConfig)
}

// OpenTsConnWithUser opens a connection to a TimescaleDB with the supplied user and pass
func OpenTsConnWithUser(db, user, pass string) (*pgx.Conn, error) {
connString := fmt.Sprintf("user=%s password=%s port=5433 dbname=%s sslmode=disable", user, pass, db)
connConfig, _ := pgx.ParseConnectionString(connString)
log.Printf("opening ts conn to '%s' with:\n%s", db, connString)
return pgx.Connect(connConfig)
}

// CreateNonAdminInTS creates a user with login and password
func CreateNonAdminInTS(user, pass string) error {
connString := fmt.Sprintf(TsConnStringTemplate, defaultPgDb)
connConfig, _ := pgx.ParseConnectionString(connString)
log.Printf("opening ts conn to '%s' with: %s", defaultPgDb, connString)
db, err := pgx.Connect(connConfig)
if err != nil {
return err
}
_, err = db.Exec(fmt.Sprintf("create user %s with login password '%s'", user, pass))
return err
}

// DeleteTimescaleDb drops a databass on the default server
func DeleteTimescaleDb(db string) error {
dbConn, err := OpenTSConn(defaultPgDb)
Expand Down

0 comments on commit 46594b9

Please sign in to comment.