From 83267a409f99107706aafb88cf8e1792b1733801 Mon Sep 17 00:00:00 2001 From: Elliot Maincourt Date: Fri, 6 Mar 2020 22:01:36 +0100 Subject: [PATCH] Fix migration Signed-off-by: Elliot Maincourt --- pkg/action/action.go | 7 ++- pkg/storage/driver/mock_test.go | 5 +- pkg/storage/driver/sql.go | 84 +++++++++++++++------------------ pkg/storage/driver/sql_test.go | 44 +++-------------- pkg/storage/driver/util.go | 16 ------- 5 files changed, 55 insertions(+), 101 deletions(-) diff --git a/pkg/action/action.go b/pkg/action/action.go index 4562c3f08..34712da01 100644 --- a/pkg/action/action.go +++ b/pkg/action/action.go @@ -258,7 +258,12 @@ func (c *Configuration) Init(getter genericclioptions.RESTClientGetter, namespac d.SetNamespace(namespace) store = storage.Init(d) case "sql": - d, err := driver.NewSQL(os.Getenv("HELM_DRIVER_SQL_DIALECT"), os.Getenv("HELM_DRIVER_SQL_CONNECTION_STRING"), log) + d, err := driver.NewSQL( + os.Getenv("HELM_DRIVER_SQL_DIALECT"), + os.Getenv("HELM_DRIVER_SQL_CONNECTION_STRING"), + log, + namespace, + ) if err != nil { panic(fmt.Sprintf("Unable to instantiate SQL driver: %v", err)) } diff --git a/pkg/storage/driver/mock_test.go b/pkg/storage/driver/mock_test.go index 08aa031f9..5a5054c0d 100644 --- a/pkg/storage/driver/mock_test.go +++ b/pkg/storage/driver/mock_test.go @@ -256,7 +256,8 @@ func newTestFixtureSQL(t *testing.T, releases ...*rspb.Release) (*SQL, sqlmock.S sqlxDB := sqlx.NewDb(sqlDB, "sqlmock") return &SQL{ - db: sqlxDB, - Log: func(a string, b ...interface{}) {}, + db: sqlxDB, + Log: func(a string, b ...interface{}) {}, + namespace: "default", }, mock } diff --git a/pkg/storage/driver/sql.go b/pkg/storage/driver/sql.go index a70ba4940..a63de02e8 100644 --- a/pkg/storage/driver/sql.go +++ b/pkg/storage/driver/sql.go @@ -51,7 +51,7 @@ var supportedSQLDialects = map[string]struct{}{ // SQLDriverName is the string name of this driver. const SQLDriverName = "SQL" -const sqlReleaseTableName = "releases.v1" +const sqlReleaseTableName = "releases_v1" const ( sqlReleaseTableKeyColumn = "key" @@ -62,7 +62,7 @@ const ( sqlReleaseTableVersionColumn = "version" sqlReleaseTableStatusColumn = "status" sqlReleaseTableOwnerColumn = "owner" - sqlReleaseTableCreatedAtColumn = "created_at" + sqlReleaseTableCreatedAtColumn = "createdAt" sqlReleaseTableModifiedAtColumn = "modifiedAt" ) @@ -92,7 +92,7 @@ func (s *SQL) ensureDBSetup() error { Id: "init", Up: []string{ ` - CREATE TABLE releases.v1 ( + CREATE TABLE releases_v1 ( key VARCHAR(67), type VARCHAR(64) NOT NULL, body TEXT NOT NULL, @@ -103,23 +103,23 @@ func (s *SQL) ensureDBSetup() error { owner TEXT NOT NULL, createdAt INTEGER NOT NULL, modifiedAt INTEGER NOT NULL DEFAULT 0, - PRIMARY KEY(name, namespace) + PRIMARY KEY(key, namespace) ); - CREATE INDEX ON releases.v1 (name, namespace); - CREATE INDEX ON releases.v1 (version); - CREATE INDEX ON releases.v1 (status); - CREATE INDEX ON releases.v1 (owner); - CREATE INDEX ON releases.v1 (createdAt); - CREATE INDEX ON releases.v1 (modifiedAt); + CREATE INDEX ON releases_v1 (name, namespace); + CREATE INDEX ON releases_v1 (version); + CREATE INDEX ON releases_v1 (status); + CREATE INDEX ON releases_v1 (owner); + CREATE INDEX ON releases_v1 (createdAt); + CREATE INDEX ON releases_v1 (modifiedAt); - GRANT ALL ON releases.v1 TO PUBLIC; + GRANT ALL ON releases_v1 TO PUBLIC; - ALTER TABLE releases.v1 ENABLE ROW LEVEL SECURITY; + ALTER TABLE releases_v1 ENABLE ROW LEVEL SECURITY; `, }, Down: []string{ ` - DROP TABLE releases.v1; + DROP TABLE releases_v1; `, }, }, @@ -154,7 +154,7 @@ type SQLReleaseWrapper struct { } // NewSQL initializes a new memory driver. -func NewSQL(dialect, connectionString string, logger func(string, ...interface{})) (*SQL, error) { +func NewSQL(dialect, connectionString string, logger func(string, ...interface{}), namespace string) (*SQL, error) { if _, ok := supportedSQLDialects[dialect]; !ok { return nil, fmt.Errorf("%s dialect isn't supported, only \"postgres\" is available for now", dialect) } @@ -173,6 +173,8 @@ func NewSQL(dialect, connectionString string, logger func(string, ...interface{} return nil, err } + driver.namespace = namespace + return driver, nil } @@ -180,13 +182,6 @@ func NewSQL(dialect, connectionString string, logger func(string, ...interface{} func (s *SQL) Get(key string) (*rspb.Release, error) { var record SQLReleaseWrapper - // We first update the current namespace - var err error - if s.namespace, err = getCurrentNamespace(); err != nil { - s.Log("an error occurred while trying to get the current namespace: %v", err) - return nil, err - } - query := fmt.Sprintf( "SELECT %s FROM %s WHERE %s = $1 AND %s = $2", sqlReleaseTableBodyColumn, @@ -220,6 +215,11 @@ func (s *SQL) List(filter func(*rspb.Release) bool) ([]*rspb.Release, error) { sqlReleaseDefaultOwner, ) + // If a namespace was specified, we only list releases from that namespace + if s.namespace != "" { + query = fmt.Sprintf("%s AND %s = '%s'", query, sqlReleaseTableNamespaceColumn, s.namespace) + } + var records = []SQLReleaseWrapper{} if err := s.db.Select(&records, query); err != nil { s.Log("list: failed to list: %v", err) @@ -258,18 +258,12 @@ func (s *SQL) Query(labels map[string]string) ([]*rspb.Release, error) { } } - // We filter out releases that do not belong to the current namespace - sqlFilterKeys = append(sqlFilterKeys, fmt.Sprintf("%s=:namespace", sqlReleaseTableNamespaceColumn)) - - // Then we update the current namespace - var err error - if s.namespace, err = getCurrentNamespace(); err != nil { - s.Log("an error occurred while trying to get the current namespace: %v", err) - return nil, err + // If a namespace was specified, we only list releases from that namespace + if s.namespace != "" { + sqlFilterKeys = append(sqlFilterKeys, fmt.Sprintf("%s=:namespace", sqlReleaseTableNamespaceColumn)) + sqlFilter["namespace"] = s.namespace } - sqlFilter["namespace"] = s.namespace - sort.Strings(sqlFilterKeys) // Build our query @@ -310,18 +304,18 @@ func (s *SQL) Query(labels map[string]string) ([]*rspb.Release, error) { // Create creates a new release. func (s *SQL) Create(key string, rls *rspb.Release) error { + namespace := rls.Namespace + if namespace == "" { + namespace = defaultNamespace + } + s.namespace = namespace + body, err := encodeRelease(rls) if err != nil { s.Log("failed to encode release: %v", err) return err } - // We update the current namespace - if s.namespace, err = getCurrentNamespace(); err != nil { - s.Log("an error occurred while trying to get the current namespace: %v", err) - return err - } - transaction, err := s.db.Beginx() if err != nil { s.Log("failed to start SQL transaction: %v", err) @@ -349,7 +343,7 @@ func (s *SQL) Create(key string, rls *rspb.Release) error { Body: body, Name: rls.Name, - Namespace: rls.Namespace, + Namespace: namespace, Version: int(rls.Version), Status: rls.Info.Status.String(), Owner: sqlReleaseDefaultOwner, @@ -382,6 +376,12 @@ func (s *SQL) Create(key string, rls *rspb.Release) error { // Update updates a release. func (s *SQL) Update(key string, rls *rspb.Release) error { + namespace := rls.Namespace + if namespace == "" { + namespace = defaultNamespace + } + s.namespace = namespace + body, err := encodeRelease(rls) if err != nil { s.Log("failed to encode release: %v", err) @@ -406,7 +406,7 @@ func (s *SQL) Update(key string, rls *rspb.Release) error { Key: key, Body: body, Name: rls.Name, - Namespace: rls.Namespace, + Namespace: namespace, Version: int(rls.Version), Status: rls.Info.Status.String(), Owner: sqlReleaseDefaultOwner, @@ -428,12 +428,6 @@ func (s *SQL) Delete(key string) (*rspb.Release, error) { return nil, fmt.Errorf("error beginning transaction: %v", err) } - // We update the current namespace - if s.namespace, err = getCurrentNamespace(); err != nil { - s.Log("an error occurred while trying to get the current namespace: %v", err) - return nil, err - } - selectQuery := fmt.Sprintf( "SELECT %s FROM %s WHERE %s=$1 AND %s=$2", sqlReleaseTableBodyColumn, diff --git a/pkg/storage/driver/sql_test.go b/pkg/storage/driver/sql_test.go index 11f8fb861..ea3cd50a7 100644 --- a/pkg/storage/driver/sql_test.go +++ b/pkg/storage/driver/sql_test.go @@ -35,12 +35,7 @@ func TestSQLName(t *testing.T) { func TestSQLGet(t *testing.T) { vers := int(1) name := "smug-pigeon" - - namespace, err := getCurrentNamespace() - if err != nil { - t.Fatalf("could not get namespace: %v", err) - } - + namespace := "default" key := testKey(name, vers) rel := releaseStub(name, vers, namespace, rspb.StatusDeployed) @@ -159,12 +154,7 @@ func TestSQLList(t *testing.T) { func TestSqlCreate(t *testing.T) { vers := 1 name := "smug-pigeon" - - namespace, err := getCurrentNamespace() - if err != nil { - t.Fatalf("could not get namespace: %v", err) - } - + namespace := "default" key := testKey(name, vers) rel := releaseStub(name, vers, namespace, rspb.StatusDeployed) @@ -204,12 +194,7 @@ func TestSqlCreate(t *testing.T) { func TestSqlCreateAlreadyExists(t *testing.T) { vers := 1 name := "smug-pigeon" - - namespace, err := getCurrentNamespace() - if err != nil { - t.Fatalf("could not get namespace: %v", err) - } - + namespace := "default" key := testKey(name, vers) rel := releaseStub(name, vers, namespace, rspb.StatusDeployed) @@ -270,12 +255,7 @@ func TestSqlCreateAlreadyExists(t *testing.T) { func TestSqlUpdate(t *testing.T) { vers := 1 name := "smug-pigeon" - - namespace, err := getCurrentNamespace() - if err != nil { - t.Fatalf("could not get namespace: %v", err) - } - + namespace := "default" key := testKey(name, vers) rel := releaseStub(name, vers, namespace, rspb.StatusDeployed) @@ -310,11 +290,6 @@ func TestSqlUpdate(t *testing.T) { } func TestSqlQuery(t *testing.T) { - namespace, err := getCurrentNamespace() - if err != nil { - t.Fatalf("could not get namespace: %v", err) - } - // Reflect actual use cases in ../storage.go labelSetDeployed := map[string]string{ "name": "smug-pigeon", @@ -346,7 +321,7 @@ func TestSqlQuery(t *testing.T) { mock. ExpectQuery(regexp.QuoteMeta(query)). - WithArgs("smug-pigeon", namespace, sqlReleaseDefaultOwner, "deployed"). + WithArgs("smug-pigeon", "default", sqlReleaseDefaultOwner, "deployed"). WillReturnRows( mock.NewRows([]string{ sqlReleaseTableBodyColumn, @@ -366,7 +341,7 @@ func TestSqlQuery(t *testing.T) { mock. ExpectQuery(regexp.QuoteMeta(query)). - WithArgs("smug-pigeon", namespace, sqlReleaseDefaultOwner). + WithArgs("smug-pigeon", "default", sqlReleaseDefaultOwner). WillReturnRows( mock.NewRows([]string{ sqlReleaseTableBodyColumn, @@ -411,12 +386,7 @@ func TestSqlQuery(t *testing.T) { func TestSqlDelete(t *testing.T) { vers := 1 name := "smug-pigeon" - - namespace, err := getCurrentNamespace() - if err != nil { - t.Fatalf("could not get namespace: %v", err) - } - + namespace := "default" key := testKey(name, vers) rel := releaseStub(name, vers, namespace, rspb.StatusDeployed) diff --git a/pkg/storage/driver/util.go b/pkg/storage/driver/util.go index 9120835d6..a87002ab4 100644 --- a/pkg/storage/driver/util.go +++ b/pkg/storage/driver/util.go @@ -23,8 +23,6 @@ import ( "encoding/json" "io/ioutil" - "k8s.io/client-go/tools/clientcmd" - rspb "helm.sh/helm/v3/pkg/release" ) @@ -84,17 +82,3 @@ func decodeRelease(data string) (*rspb.Release, error) { } return &rls, nil } - -// getCurrentNamespace gets the current namespace from the local context -func getCurrentNamespace() (string, error) { - rules := clientcmd.NewDefaultClientConfigLoadingRules() - rules.DefaultClientConfig = &clientcmd.DefaultClientConfig - - cfg := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(rules, &clientcmd.ConfigOverrides{ - ClusterDefaults: clientcmd.ClusterDefaults, - }) - - namespace, _, err := cfg.Namespace() - - return namespace, err -}