Fix migration

Signed-off-by: Elliot Maincourt <e.maincourt@gmail.com>
pull/7635/head
Elliot Maincourt 6 years ago
parent 03f9f680dc
commit 83267a409f

@ -258,7 +258,12 @@ func (c *Configuration) Init(getter genericclioptions.RESTClientGetter, namespac
d.SetNamespace(namespace) d.SetNamespace(namespace)
store = storage.Init(d) store = storage.Init(d)
case "sql": 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 { if err != nil {
panic(fmt.Sprintf("Unable to instantiate SQL driver: %v", err)) panic(fmt.Sprintf("Unable to instantiate SQL driver: %v", err))
} }

@ -258,5 +258,6 @@ func newTestFixtureSQL(t *testing.T, releases ...*rspb.Release) (*SQL, sqlmock.S
return &SQL{ return &SQL{
db: sqlxDB, db: sqlxDB,
Log: func(a string, b ...interface{}) {}, Log: func(a string, b ...interface{}) {},
namespace: "default",
}, mock }, mock
} }

@ -51,7 +51,7 @@ var supportedSQLDialects = map[string]struct{}{
// SQLDriverName is the string name of this driver. // SQLDriverName is the string name of this driver.
const SQLDriverName = "SQL" const SQLDriverName = "SQL"
const sqlReleaseTableName = "releases.v1" const sqlReleaseTableName = "releases_v1"
const ( const (
sqlReleaseTableKeyColumn = "key" sqlReleaseTableKeyColumn = "key"
@ -62,7 +62,7 @@ const (
sqlReleaseTableVersionColumn = "version" sqlReleaseTableVersionColumn = "version"
sqlReleaseTableStatusColumn = "status" sqlReleaseTableStatusColumn = "status"
sqlReleaseTableOwnerColumn = "owner" sqlReleaseTableOwnerColumn = "owner"
sqlReleaseTableCreatedAtColumn = "created_at" sqlReleaseTableCreatedAtColumn = "createdAt"
sqlReleaseTableModifiedAtColumn = "modifiedAt" sqlReleaseTableModifiedAtColumn = "modifiedAt"
) )
@ -92,7 +92,7 @@ func (s *SQL) ensureDBSetup() error {
Id: "init", Id: "init",
Up: []string{ Up: []string{
` `
CREATE TABLE releases.v1 ( CREATE TABLE releases_v1 (
key VARCHAR(67), key VARCHAR(67),
type VARCHAR(64) NOT NULL, type VARCHAR(64) NOT NULL,
body TEXT NOT NULL, body TEXT NOT NULL,
@ -103,23 +103,23 @@ func (s *SQL) ensureDBSetup() error {
owner TEXT NOT NULL, owner TEXT NOT NULL,
createdAt INTEGER NOT NULL, createdAt INTEGER NOT NULL,
modifiedAt INTEGER NOT NULL DEFAULT 0, 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 (name, namespace);
CREATE INDEX ON releases.v1 (version); CREATE INDEX ON releases_v1 (version);
CREATE INDEX ON releases.v1 (status); CREATE INDEX ON releases_v1 (status);
CREATE INDEX ON releases.v1 (owner); CREATE INDEX ON releases_v1 (owner);
CREATE INDEX ON releases.v1 (createdAt); CREATE INDEX ON releases_v1 (createdAt);
CREATE INDEX ON releases.v1 (modifiedAt); 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{ Down: []string{
` `
DROP TABLE releases.v1; DROP TABLE releases_v1;
`, `,
}, },
}, },
@ -154,7 +154,7 @@ type SQLReleaseWrapper struct {
} }
// NewSQL initializes a new memory driver. // 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 { if _, ok := supportedSQLDialects[dialect]; !ok {
return nil, fmt.Errorf("%s dialect isn't supported, only \"postgres\" is available for now", dialect) 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 return nil, err
} }
driver.namespace = namespace
return driver, nil 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) { func (s *SQL) Get(key string) (*rspb.Release, error) {
var record SQLReleaseWrapper 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( query := fmt.Sprintf(
"SELECT %s FROM %s WHERE %s = $1 AND %s = $2", "SELECT %s FROM %s WHERE %s = $1 AND %s = $2",
sqlReleaseTableBodyColumn, sqlReleaseTableBodyColumn,
@ -220,6 +215,11 @@ func (s *SQL) List(filter func(*rspb.Release) bool) ([]*rspb.Release, error) {
sqlReleaseDefaultOwner, 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{} var records = []SQLReleaseWrapper{}
if err := s.db.Select(&records, query); err != nil { if err := s.db.Select(&records, query); err != nil {
s.Log("list: failed to list: %v", err) s.Log("list: failed to list: %v", err)
@ -258,17 +258,11 @@ func (s *SQL) Query(labels map[string]string) ([]*rspb.Release, error) {
} }
} }
// We filter out releases that do not belong to the current namespace // If a namespace was specified, we only list releases from that namespace
if s.namespace != "" {
sqlFilterKeys = append(sqlFilterKeys, fmt.Sprintf("%s=:namespace", sqlReleaseTableNamespaceColumn)) 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
}
sqlFilter["namespace"] = s.namespace sqlFilter["namespace"] = s.namespace
}
sort.Strings(sqlFilterKeys) sort.Strings(sqlFilterKeys)
@ -310,18 +304,18 @@ func (s *SQL) Query(labels map[string]string) ([]*rspb.Release, error) {
// Create creates a new release. // Create creates a new release.
func (s *SQL) Create(key string, rls *rspb.Release) error { func (s *SQL) Create(key string, rls *rspb.Release) error {
namespace := rls.Namespace
if namespace == "" {
namespace = defaultNamespace
}
s.namespace = namespace
body, err := encodeRelease(rls) body, err := encodeRelease(rls)
if err != nil { if err != nil {
s.Log("failed to encode release: %v", err) s.Log("failed to encode release: %v", err)
return 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() transaction, err := s.db.Beginx()
if err != nil { if err != nil {
s.Log("failed to start SQL transaction: %v", err) 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, Body: body,
Name: rls.Name, Name: rls.Name,
Namespace: rls.Namespace, Namespace: namespace,
Version: int(rls.Version), Version: int(rls.Version),
Status: rls.Info.Status.String(), Status: rls.Info.Status.String(),
Owner: sqlReleaseDefaultOwner, Owner: sqlReleaseDefaultOwner,
@ -382,6 +376,12 @@ func (s *SQL) Create(key string, rls *rspb.Release) error {
// Update updates a release. // Update updates a release.
func (s *SQL) Update(key string, rls *rspb.Release) error { func (s *SQL) Update(key string, rls *rspb.Release) error {
namespace := rls.Namespace
if namespace == "" {
namespace = defaultNamespace
}
s.namespace = namespace
body, err := encodeRelease(rls) body, err := encodeRelease(rls)
if err != nil { if err != nil {
s.Log("failed to encode release: %v", err) s.Log("failed to encode release: %v", err)
@ -406,7 +406,7 @@ func (s *SQL) Update(key string, rls *rspb.Release) error {
Key: key, Key: key,
Body: body, Body: body,
Name: rls.Name, Name: rls.Name,
Namespace: rls.Namespace, Namespace: namespace,
Version: int(rls.Version), Version: int(rls.Version),
Status: rls.Info.Status.String(), Status: rls.Info.Status.String(),
Owner: sqlReleaseDefaultOwner, Owner: sqlReleaseDefaultOwner,
@ -428,12 +428,6 @@ func (s *SQL) Delete(key string) (*rspb.Release, error) {
return nil, fmt.Errorf("error beginning transaction: %v", err) 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( selectQuery := fmt.Sprintf(
"SELECT %s FROM %s WHERE %s=$1 AND %s=$2", "SELECT %s FROM %s WHERE %s=$1 AND %s=$2",
sqlReleaseTableBodyColumn, sqlReleaseTableBodyColumn,

@ -35,12 +35,7 @@ func TestSQLName(t *testing.T) {
func TestSQLGet(t *testing.T) { func TestSQLGet(t *testing.T) {
vers := int(1) vers := int(1)
name := "smug-pigeon" name := "smug-pigeon"
namespace := "default"
namespace, err := getCurrentNamespace()
if err != nil {
t.Fatalf("could not get namespace: %v", err)
}
key := testKey(name, vers) key := testKey(name, vers)
rel := releaseStub(name, vers, namespace, rspb.StatusDeployed) rel := releaseStub(name, vers, namespace, rspb.StatusDeployed)
@ -159,12 +154,7 @@ func TestSQLList(t *testing.T) {
func TestSqlCreate(t *testing.T) { func TestSqlCreate(t *testing.T) {
vers := 1 vers := 1
name := "smug-pigeon" name := "smug-pigeon"
namespace := "default"
namespace, err := getCurrentNamespace()
if err != nil {
t.Fatalf("could not get namespace: %v", err)
}
key := testKey(name, vers) key := testKey(name, vers)
rel := releaseStub(name, vers, namespace, rspb.StatusDeployed) rel := releaseStub(name, vers, namespace, rspb.StatusDeployed)
@ -204,12 +194,7 @@ func TestSqlCreate(t *testing.T) {
func TestSqlCreateAlreadyExists(t *testing.T) { func TestSqlCreateAlreadyExists(t *testing.T) {
vers := 1 vers := 1
name := "smug-pigeon" name := "smug-pigeon"
namespace := "default"
namespace, err := getCurrentNamespace()
if err != nil {
t.Fatalf("could not get namespace: %v", err)
}
key := testKey(name, vers) key := testKey(name, vers)
rel := releaseStub(name, vers, namespace, rspb.StatusDeployed) rel := releaseStub(name, vers, namespace, rspb.StatusDeployed)
@ -270,12 +255,7 @@ func TestSqlCreateAlreadyExists(t *testing.T) {
func TestSqlUpdate(t *testing.T) { func TestSqlUpdate(t *testing.T) {
vers := 1 vers := 1
name := "smug-pigeon" name := "smug-pigeon"
namespace := "default"
namespace, err := getCurrentNamespace()
if err != nil {
t.Fatalf("could not get namespace: %v", err)
}
key := testKey(name, vers) key := testKey(name, vers)
rel := releaseStub(name, vers, namespace, rspb.StatusDeployed) rel := releaseStub(name, vers, namespace, rspb.StatusDeployed)
@ -310,11 +290,6 @@ func TestSqlUpdate(t *testing.T) {
} }
func TestSqlQuery(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 // Reflect actual use cases in ../storage.go
labelSetDeployed := map[string]string{ labelSetDeployed := map[string]string{
"name": "smug-pigeon", "name": "smug-pigeon",
@ -346,7 +321,7 @@ func TestSqlQuery(t *testing.T) {
mock. mock.
ExpectQuery(regexp.QuoteMeta(query)). ExpectQuery(regexp.QuoteMeta(query)).
WithArgs("smug-pigeon", namespace, sqlReleaseDefaultOwner, "deployed"). WithArgs("smug-pigeon", "default", sqlReleaseDefaultOwner, "deployed").
WillReturnRows( WillReturnRows(
mock.NewRows([]string{ mock.NewRows([]string{
sqlReleaseTableBodyColumn, sqlReleaseTableBodyColumn,
@ -366,7 +341,7 @@ func TestSqlQuery(t *testing.T) {
mock. mock.
ExpectQuery(regexp.QuoteMeta(query)). ExpectQuery(regexp.QuoteMeta(query)).
WithArgs("smug-pigeon", namespace, sqlReleaseDefaultOwner). WithArgs("smug-pigeon", "default", sqlReleaseDefaultOwner).
WillReturnRows( WillReturnRows(
mock.NewRows([]string{ mock.NewRows([]string{
sqlReleaseTableBodyColumn, sqlReleaseTableBodyColumn,
@ -411,12 +386,7 @@ func TestSqlQuery(t *testing.T) {
func TestSqlDelete(t *testing.T) { func TestSqlDelete(t *testing.T) {
vers := 1 vers := 1
name := "smug-pigeon" name := "smug-pigeon"
namespace := "default"
namespace, err := getCurrentNamespace()
if err != nil {
t.Fatalf("could not get namespace: %v", err)
}
key := testKey(name, vers) key := testKey(name, vers)
rel := releaseStub(name, vers, namespace, rspb.StatusDeployed) rel := releaseStub(name, vers, namespace, rspb.StatusDeployed)

@ -23,8 +23,6 @@ import (
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"k8s.io/client-go/tools/clientcmd"
rspb "helm.sh/helm/v3/pkg/release" rspb "helm.sh/helm/v3/pkg/release"
) )
@ -84,17 +82,3 @@ func decodeRelease(data string) (*rspb.Release, error) {
} }
return &rls, nil 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
}

Loading…
Cancel
Save