configstore: use augmented types for vars/secrets dynamic values

This commit is contained in:
Simone Gotti 2019-04-30 16:28:01 +02:00
parent da2ac0ab38
commit 984efb539e
9 changed files with 206 additions and 165 deletions

View File

@ -156,48 +156,48 @@ func (c *Client) DeleteProject(ctx context.Context, projectRef string) (*http.Re
return c.getResponse(ctx, "DELETE", fmt.Sprintf("/projects/%s", url.PathEscape(projectRef)), nil, jsonContent, nil) return c.getResponse(ctx, "DELETE", fmt.Sprintf("/projects/%s", url.PathEscape(projectRef)), nil, jsonContent, nil)
} }
func (c *Client) GetProjectGroupSecrets(ctx context.Context, projectGroupRef string, tree bool) ([]*types.Secret, *http.Response, error) { func (c *Client) GetProjectGroupSecrets(ctx context.Context, projectGroupRef string, tree bool) ([]*Secret, *http.Response, error) {
q := url.Values{} q := url.Values{}
if tree { if tree {
q.Add("tree", "") q.Add("tree", "")
} }
secrets := []*types.Secret{} secrets := []*Secret{}
resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/projectgroups/%s/secrets", url.PathEscape(projectGroupRef)), q, jsonContent, nil, &secrets) resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/projectgroups/%s/secrets", url.PathEscape(projectGroupRef)), q, jsonContent, nil, &secrets)
return secrets, resp, err return secrets, resp, err
} }
func (c *Client) GetProjectSecrets(ctx context.Context, projectRef string, tree bool) ([]*types.Secret, *http.Response, error) { func (c *Client) GetProjectSecrets(ctx context.Context, projectRef string, tree bool) ([]*Secret, *http.Response, error) {
q := url.Values{} q := url.Values{}
if tree { if tree {
q.Add("tree", "") q.Add("tree", "")
} }
secrets := []*types.Secret{} secrets := []*Secret{}
resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/projects/%s/secrets", url.PathEscape(projectRef)), q, jsonContent, nil, &secrets) resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/projects/%s/secrets", url.PathEscape(projectRef)), q, jsonContent, nil, &secrets)
return secrets, resp, err return secrets, resp, err
} }
func (c *Client) CreateProjectGroupSecret(ctx context.Context, projectGroupRef string, secret *types.Secret) (*types.Secret, *http.Response, error) { func (c *Client) CreateProjectGroupSecret(ctx context.Context, projectGroupRef string, secret *types.Secret) (*Secret, *http.Response, error) {
pj, err := json.Marshal(secret) pj, err := json.Marshal(secret)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
secret = new(types.Secret) resSecret := new(Secret)
resp, err := c.getParsedResponse(ctx, "POST", fmt.Sprintf("/projectgroups/%s/secrets", url.PathEscape(projectGroupRef)), nil, jsonContent, bytes.NewReader(pj), secret) resp, err := c.getParsedResponse(ctx, "POST", fmt.Sprintf("/projectgroups/%s/secrets", url.PathEscape(projectGroupRef)), nil, jsonContent, bytes.NewReader(pj), resSecret)
return secret, resp, err return resSecret, resp, err
} }
func (c *Client) CreateProjectSecret(ctx context.Context, projectRef string, secret *types.Secret) (*types.Secret, *http.Response, error) { func (c *Client) CreateProjectSecret(ctx context.Context, projectRef string, secret *types.Secret) (*Secret, *http.Response, error) {
pj, err := json.Marshal(secret) pj, err := json.Marshal(secret)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
secret = new(types.Secret) resSecret := new(Secret)
resp, err := c.getParsedResponse(ctx, "POST", fmt.Sprintf("/projects/%s/secrets", url.PathEscape(projectRef)), nil, jsonContent, bytes.NewReader(pj), secret) resp, err := c.getParsedResponse(ctx, "POST", fmt.Sprintf("/projects/%s/secrets", url.PathEscape(projectRef)), nil, jsonContent, bytes.NewReader(pj), resSecret)
return secret, resp, err return resSecret, resp, err
} }
func (c *Client) DeleteProjectGroupSecret(ctx context.Context, projectGroupRef, secretName string) (*http.Response, error) { func (c *Client) DeleteProjectGroupSecret(ctx context.Context, projectGroupRef, secretName string) (*http.Response, error) {
@ -208,48 +208,48 @@ func (c *Client) DeleteProjectSecret(ctx context.Context, projectRef, secretName
return c.getResponse(ctx, "DELETE", fmt.Sprintf("/projects/%s/secrets/%s", url.PathEscape(projectRef), secretName), nil, jsonContent, nil) return c.getResponse(ctx, "DELETE", fmt.Sprintf("/projects/%s/secrets/%s", url.PathEscape(projectRef), secretName), nil, jsonContent, nil)
} }
func (c *Client) GetProjectGroupVariables(ctx context.Context, projectGroupRef string, tree bool) ([]*types.Variable, *http.Response, error) { func (c *Client) GetProjectGroupVariables(ctx context.Context, projectGroupRef string, tree bool) ([]*Variable, *http.Response, error) {
q := url.Values{} q := url.Values{}
if tree { if tree {
q.Add("tree", "") q.Add("tree", "")
} }
variables := []*types.Variable{} variables := []*Variable{}
resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/projectgroups/%s/variables", url.PathEscape(projectGroupRef)), q, jsonContent, nil, &variables) resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/projectgroups/%s/variables", url.PathEscape(projectGroupRef)), q, jsonContent, nil, &variables)
return variables, resp, err return variables, resp, err
} }
func (c *Client) GetProjectVariables(ctx context.Context, projectRef string, tree bool) ([]*types.Variable, *http.Response, error) { func (c *Client) GetProjectVariables(ctx context.Context, projectRef string, tree bool) ([]*Variable, *http.Response, error) {
q := url.Values{} q := url.Values{}
if tree { if tree {
q.Add("tree", "") q.Add("tree", "")
} }
variables := []*types.Variable{} variables := []*Variable{}
resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/projects/%s/variables", url.PathEscape(projectRef)), q, jsonContent, nil, &variables) resp, err := c.getParsedResponse(ctx, "GET", fmt.Sprintf("/projects/%s/variables", url.PathEscape(projectRef)), q, jsonContent, nil, &variables)
return variables, resp, err return variables, resp, err
} }
func (c *Client) CreateProjectGroupVariable(ctx context.Context, projectGroupRef string, variable *types.Variable) (*types.Variable, *http.Response, error) { func (c *Client) CreateProjectGroupVariable(ctx context.Context, projectGroupRef string, variable *types.Variable) (*Variable, *http.Response, error) {
pj, err := json.Marshal(variable) pj, err := json.Marshal(variable)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
variable = new(types.Variable) resVariable := new(Variable)
resp, err := c.getParsedResponse(ctx, "POST", fmt.Sprintf("/projectgroups/%s/variables", url.PathEscape(projectGroupRef)), nil, jsonContent, bytes.NewReader(pj), variable) resp, err := c.getParsedResponse(ctx, "POST", fmt.Sprintf("/projectgroups/%s/variables", url.PathEscape(projectGroupRef)), nil, jsonContent, bytes.NewReader(pj), resVariable)
return variable, resp, err return resVariable, resp, err
} }
func (c *Client) CreateProjectVariable(ctx context.Context, projectRef string, variable *types.Variable) (*types.Variable, *http.Response, error) { func (c *Client) CreateProjectVariable(ctx context.Context, projectRef string, variable *types.Variable) (*Variable, *http.Response, error) {
pj, err := json.Marshal(variable) pj, err := json.Marshal(variable)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
variable = new(types.Variable) resVariable := new(Variable)
resp, err := c.getParsedResponse(ctx, "POST", fmt.Sprintf("/projects/%s/variables", url.PathEscape(projectRef)), nil, jsonContent, bytes.NewReader(pj), variable) resp, err := c.getParsedResponse(ctx, "POST", fmt.Sprintf("/projects/%s/variables", url.PathEscape(projectRef)), nil, jsonContent, bytes.NewReader(pj), resVariable)
return variable, resp, err return resVariable, resp, err
} }
func (c *Client) DeleteProjectGroupVariable(ctx context.Context, projectGroupRef, variableName string) (*http.Response, error) { func (c *Client) DeleteProjectGroupVariable(ctx context.Context, projectGroupRef, variableName string) (*http.Response, error) {

View File

@ -29,6 +29,14 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
) )
// Secret augments types.Secret with dynamic data
type Secret struct {
*types.Secret
// dynamic data
ParentPath string
}
type SecretHandler struct { type SecretHandler struct {
log *zap.SugaredLogger log *zap.SugaredLogger
readDB *readdb.ReadDB readDB *readdb.ReadDB
@ -95,13 +103,27 @@ func (h *SecretsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} else { } else {
secrets, err = h.readDB.GetSecrets(tx, parentID) secrets, err = h.readDB.GetSecrets(tx, parentID)
} }
return err
})
if err != nil {
h.log.Errorf("err: %+v", err)
httpError(w, err)
return
}
resSecrets := make([]*Secret, len(secrets))
for i, s := range secrets {
resSecrets[i] = &Secret{Secret: s}
}
err = h.readDB.Do(func(tx *db.Tx) error {
// populate parent path // populate parent path
for _, s := range secrets { for _, s := range resSecrets {
pp, err := h.readDB.GetParentPath(tx, s.Parent.Type, s.Parent.ID) pp, err := h.readDB.GetParentPath(tx, s.Parent.Type, s.Parent.ID)
if err != nil { if err != nil {
return err return err
} }
s.Parent.Path = pp s.ParentPath = pp
} }
return err return err
}) })
@ -111,7 +133,7 @@ func (h *SecretsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return return
} }
if err := httpResponse(w, http.StatusOK, secrets); err != nil { if err := httpResponse(w, http.StatusOK, resSecrets); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }

View File

@ -28,6 +28,14 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
) )
// Variable augments types.Variable with dynamic data
type Variable struct {
*types.Variable
// dynamic data
ParentPath string
}
type VariablesHandler struct { type VariablesHandler struct {
log *zap.SugaredLogger log *zap.SugaredLogger
readDB *readdb.ReadDB readDB *readdb.ReadDB
@ -59,13 +67,26 @@ func (h *VariablesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} else { } else {
variables, err = h.readDB.GetVariables(tx, parentID) variables, err = h.readDB.GetVariables(tx, parentID)
} }
return err
})
if err != nil {
h.log.Errorf("err: %+v", err)
httpError(w, err)
return
}
resVariables := make([]*Variable, len(variables))
for i, v := range variables {
resVariables[i] = &Variable{Variable: v}
}
err = h.readDB.Do(func(tx *db.Tx) error {
// populate parent path // populate parent path
for _, v := range variables { for _, v := range resVariables {
pp, err := h.readDB.GetParentPath(tx, v.Parent.Type, v.Parent.ID) pp, err := h.readDB.GetParentPath(tx, v.Parent.Type, v.Parent.ID)
if err != nil { if err != nil {
return err return err
} }
v.Parent.Path = pp v.ParentPath = pp
} }
return err return err
}) })
@ -75,7 +96,7 @@ func (h *VariablesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return return
} }
if err := httpResponse(w, http.StatusOK, variables); err != nil { if err := httpResponse(w, http.StatusOK, resVariables); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }
} }
@ -108,8 +129,6 @@ func (h *CreateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
variable.Parent.Type = parentType variable.Parent.Type = parentType
variable.Parent.ID = parentRef variable.Parent.ID = parentRef
h.log.Infof("variable: %s", util.Dump(variable))
variable, err = h.ch.CreateVariable(ctx, variable) variable, err = h.ch.CreateVariable(ctx, variable)
if httpError(w, err) { if httpError(w, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)

View File

@ -33,11 +33,11 @@ type SecretResponse struct {
ParentPath string `json:"parent_path"` ParentPath string `json:"parent_path"`
} }
func createSecretResponse(s *types.Secret) *SecretResponse { func createSecretResponse(s *csapi.Secret) *SecretResponse {
return &SecretResponse{ return &SecretResponse{
ID: s.ID, ID: s.ID,
Name: s.Name, Name: s.Name,
ParentPath: s.Parent.Path, ParentPath: s.ParentPath,
} }
} }
@ -61,7 +61,7 @@ func (h *SecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return return
} }
var cssecrets []*types.Secret var cssecrets []*csapi.Secret
var resp *http.Response var resp *http.Response
switch parentType { switch parentType {
case types.ConfigTypeProjectGroup: case types.ConfigTypeProjectGroup:
@ -132,21 +132,22 @@ func (h *CreateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
} }
var resp *http.Response var resp *http.Response
var rs *csapi.Secret
switch parentType { switch parentType {
case types.ConfigTypeProjectGroup: case types.ConfigTypeProjectGroup:
h.log.Infof("creating project group secret") h.log.Infof("creating project group secret")
s, resp, err = h.configstoreClient.CreateProjectGroupSecret(ctx, parentRef, s) rs, resp, err = h.configstoreClient.CreateProjectGroupSecret(ctx, parentRef, s)
case types.ConfigTypeProject: case types.ConfigTypeProject:
h.log.Infof("creating project secret") h.log.Infof("creating project secret")
s, resp, err = h.configstoreClient.CreateProjectSecret(ctx, parentRef, s) rs, resp, err = h.configstoreClient.CreateProjectSecret(ctx, parentRef, s)
} }
if httpErrorFromRemote(w, resp, err) { if httpErrorFromRemote(w, resp, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
h.log.Infof("secret %s created, ID: %s", s.Name, s.ID) h.log.Infof("secret %s created, ID: %s", rs.Name, rs.ID)
res := createSecretResponse(s) res := createSecretResponse(rs)
if err := httpResponse(w, http.StatusOK, res); err != nil { if err := httpResponse(w, http.StatusOK, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }

View File

@ -43,12 +43,12 @@ type VariableResponse struct {
ParentPath string `json:"parent_path"` ParentPath string `json:"parent_path"`
} }
func createVariableResponse(v *types.Variable, secrets []*types.Secret) *VariableResponse { func createVariableResponse(v *csapi.Variable, secrets []*csapi.Secret) *VariableResponse {
nv := &VariableResponse{ nv := &VariableResponse{
ID: v.ID, ID: v.ID,
Name: v.Name, Name: v.Name,
Values: make([]VariableValue, len(v.Values)), Values: make([]VariableValue, len(v.Values)),
ParentPath: v.Parent.Path, ParentPath: v.ParentPath,
} }
for i, varvalue := range v.Values { for i, varvalue := range v.Values {
@ -58,9 +58,9 @@ func createVariableResponse(v *types.Variable, secrets []*types.Secret) *Variabl
When: varvalue.When, When: varvalue.When,
} }
// get matching secret for var value // get matching secret for var value
secret := common.GetVarValueMatchingSecret(varvalue, v.Parent.Path, secrets) secret := common.GetVarValueMatchingSecret(varvalue, v.ParentPath, secrets)
if secret != nil { if secret != nil {
nv.Values[i].MatchingSecretParentPath = secret.Parent.Path nv.Values[i].MatchingSecretParentPath = secret.ParentPath
} }
} }
@ -88,8 +88,8 @@ func (h *VariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return return
} }
var csvars []*types.Variable var csvars []*csapi.Variable
var cssecrets []*types.Secret var cssecrets []*csapi.Secret
switch parentType { switch parentType {
case types.ConfigTypeProjectGroup: case types.ConfigTypeProjectGroup:
@ -184,7 +184,8 @@ func (h *CreateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
Values: req.Values, Values: req.Values,
} }
var cssecrets []*types.Secret var cssecrets []*csapi.Secret
var rv *csapi.Variable
switch parentType { switch parentType {
case types.ConfigTypeProjectGroup: case types.ConfigTypeProjectGroup:
@ -197,7 +198,7 @@ func (h *CreateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
} }
h.log.Infof("creating project group variable") h.log.Infof("creating project group variable")
v, resp, err = h.configstoreClient.CreateProjectGroupVariable(ctx, parentRef, v) rv, resp, err = h.configstoreClient.CreateProjectGroupVariable(ctx, parentRef, v)
if httpErrorFromRemote(w, resp, err) { if httpErrorFromRemote(w, resp, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
@ -212,15 +213,15 @@ func (h *CreateVariableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
} }
h.log.Infof("creating project variable") h.log.Infof("creating project variable")
v, resp, err = h.configstoreClient.CreateProjectVariable(ctx, parentRef, v) rv, resp, err = h.configstoreClient.CreateProjectVariable(ctx, parentRef, v)
if httpErrorFromRemote(w, resp, err) { if httpErrorFromRemote(w, resp, err) {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
return return
} }
} }
h.log.Infof("variable %s created, ID: %s", v.Name, v.ID) h.log.Infof("variable %s created, ID: %s", rv.Name, rv.ID)
res := createVariableResponse(v, cssecrets) res := createVariableResponse(rv, cssecrets)
if err := httpResponse(w, http.StatusCreated, res); err != nil { if err := httpResponse(w, http.StatusCreated, res); err != nil {
h.log.Errorf("err: %+v", err) h.log.Errorf("err: %+v", err)
} }

View File

@ -15,20 +15,20 @@
package common package common
import ( import (
"strings" csapi "github.com/sorintlab/agola/internal/services/configstore/api"
"github.com/sorintlab/agola/internal/services/types" "github.com/sorintlab/agola/internal/services/types"
"github.com/sorintlab/agola/internal/util"
) )
func FilterOverridenVariables(variables []*types.Variable) []*types.Variable { func FilterOverridenVariables(variables []*csapi.Variable) []*csapi.Variable {
variablesMap := map[string]*types.Variable{} variablesMap := map[string]*csapi.Variable{}
for _, v := range variables { for _, v := range variables {
if _, ok := variablesMap[v.Name]; !ok { if _, ok := variablesMap[v.Name]; !ok {
variablesMap[v.Name] = v variablesMap[v.Name] = v
} }
} }
filteredVariables := make([]*types.Variable, len(variablesMap)) filteredVariables := make([]*csapi.Variable, len(variablesMap))
i := 0 i := 0
// keep the original order // keep the original order
for _, v := range variables { for _, v := range variables {
@ -43,15 +43,15 @@ func FilterOverridenVariables(variables []*types.Variable) []*types.Variable {
return filteredVariables return filteredVariables
} }
func GetVarValueMatchingSecret(varval types.VariableValue, varParentPath string, secrets []*types.Secret) *types.Secret { func GetVarValueMatchingSecret(varval types.VariableValue, varParentPath string, secrets []*csapi.Secret) *csapi.Secret {
// get the secret value referenced by the variable, it must be a secret at the same level or a lower level // get the secret value referenced by the variable, it must be a secret at the same level or a lower level
var secret *types.Secret var secret *csapi.Secret
for _, s := range secrets { for _, s := range secrets {
// we assume the root path will be the same // we assume the root path will be the same
if s.Name != varval.SecretName { if s.Name != varval.SecretName {
continue continue
} }
if strings.Contains(varParentPath, s.Parent.Path) { if util.IsSameOrParentPath(s.ParentPath, varParentPath) {
secret = s secret = s
break break
} }

View File

@ -18,86 +18,87 @@ import (
"testing" "testing"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
csapi "github.com/sorintlab/agola/internal/services/configstore/api"
"github.com/sorintlab/agola/internal/services/types" "github.com/sorintlab/agola/internal/services/types"
) )
func TestFilterOverridenVariables(t *testing.T) { func TestFilterOverridenVariables(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
variables []*types.Variable variables []*csapi.Variable
out []*types.Variable out []*csapi.Variable
}{ }{
{ {
name: "test empty variables", name: "test empty variables",
variables: []*types.Variable{}, variables: []*csapi.Variable{},
out: []*types.Variable{}, out: []*csapi.Variable{},
}, },
{ {
name: "test variable overrides", name: "test variable overrides",
variables: []*types.Variable{ variables: []*csapi.Variable{
// variables must be in depth (from leaves to root) order as returned by the // variables must be in depth (from leaves to root) order as returned by the
// configstore apis // configstore apis
&types.Variable{ &csapi.Variable{
Variable: &types.Variable{
Name: "var04", Name: "var04",
Parent: types.Parent{
Path: "org/org01/projectgroup02/projectgroup03/project02",
}, },
ParentPath: "org/org01/projectgroup02/projectgroup03/project02",
}, },
&types.Variable{ &csapi.Variable{
Variable: &types.Variable{
Name: "var03", Name: "var03",
Parent: types.Parent{
Path: "org/org01/projectgroup01/project01",
}, },
ParentPath: "org/org01/projectgroup01/project01",
}, },
&types.Variable{ &csapi.Variable{
Variable: &types.Variable{
Name: "var02", Name: "var02",
Parent: types.Parent{
Path: "org/org01/projectgroup01/project01",
}, },
ParentPath: "org/org01/projectgroup01/project01",
}, },
&types.Variable{ &csapi.Variable{
Variable: &types.Variable{
Name: "var02", Name: "var02",
Parent: types.Parent{
Path: "org/org01/projectgroup01",
}, },
ParentPath: "org/org01/projectgroup01",
}, },
&types.Variable{ &csapi.Variable{
Variable: &types.Variable{
Name: "var01", Name: "var01",
Parent: types.Parent{
Path: "org/org01/projectgroup01",
}, },
ParentPath: "org/org01/projectgroup01",
}, },
&types.Variable{ &csapi.Variable{
Variable: &types.Variable{
Name: "var01", Name: "var01",
Parent: types.Parent{ },
Path: "org/org01", ParentPath: "org/org01",
}, },
}, },
}, out: []*csapi.Variable{
out: []*types.Variable{ &csapi.Variable{
&types.Variable{ Variable: &types.Variable{
Name: "var04", Name: "var04",
Parent: types.Parent{
Path: "org/org01/projectgroup02/projectgroup03/project02",
}, },
ParentPath: "org/org01/projectgroup02/projectgroup03/project02",
}, },
&types.Variable{ &csapi.Variable{
Variable: &types.Variable{
Name: "var03", Name: "var03",
Parent: types.Parent{
Path: "org/org01/projectgroup01/project01",
}, },
ParentPath: "org/org01/projectgroup01/project01",
}, },
&types.Variable{ &csapi.Variable{
Variable: &types.Variable{
Name: "var02", Name: "var02",
Parent: types.Parent{
Path: "org/org01/projectgroup01/project01",
}, },
ParentPath: "org/org01/projectgroup01/project01",
}, },
&types.Variable{ &csapi.Variable{
Variable: &types.Variable{
Name: "var01", Name: "var01",
Parent: types.Parent{
Path: "org/org01/projectgroup01",
}, },
ParentPath: "org/org01/projectgroup01",
}, },
}, },
}, },
@ -119,8 +120,8 @@ func TestGetVarValueMatchingSecret(t *testing.T) {
name string name string
varValue types.VariableValue varValue types.VariableValue
varParentPath string varParentPath string
secrets []*types.Secret secrets []*csapi.Secret
out *types.Secret out *csapi.Secret
}{ }{
{ {
name: "test empty secrets", name: "test empty secrets",
@ -129,7 +130,7 @@ func TestGetVarValueMatchingSecret(t *testing.T) {
SecretVar: "secretvar01", SecretVar: "secretvar01",
}, },
varParentPath: "org/org01/projectgroup01/project01", varParentPath: "org/org01/projectgroup01/project01",
secrets: []*types.Secret{}, secrets: []*csapi.Secret{},
out: nil, out: nil,
}, },
{ {
@ -139,12 +140,12 @@ func TestGetVarValueMatchingSecret(t *testing.T) {
SecretVar: "secretvar01", SecretVar: "secretvar01",
}, },
varParentPath: "org/org01/projectgroup01/projectgroup02", varParentPath: "org/org01/projectgroup01/projectgroup02",
secrets: []*types.Secret{ secrets: []*csapi.Secret{
&types.Secret{ &csapi.Secret{
Secret: &types.Secret{
Name: "secret02", Name: "secret02",
Parent: types.Parent{
Path: "org/org01/projectgroup01/projectgroup02",
}, },
ParentPath: "org/org01/projectgroup01/projectgroup02",
}, },
}, },
out: nil, out: nil,
@ -156,12 +157,12 @@ func TestGetVarValueMatchingSecret(t *testing.T) {
SecretVar: "secretvar01", SecretVar: "secretvar01",
}, },
varParentPath: "org/org01/projectgroup01/projectgroup02", varParentPath: "org/org01/projectgroup01/projectgroup02",
secrets: []*types.Secret{ secrets: []*csapi.Secret{
&types.Secret{ &csapi.Secret{
Secret: &types.Secret{
Name: "secret02", Name: "secret02",
Parent: types.Parent{
Path: "org/org01/projectgroup01/projectgroup03",
}, },
ParentPath: "org/org01/projectgroup01/projectgroup03",
}, },
}, },
out: nil, out: nil,
@ -173,12 +174,12 @@ func TestGetVarValueMatchingSecret(t *testing.T) {
SecretVar: "secretvar01", SecretVar: "secretvar01",
}, },
varParentPath: "org/org01/projectgroup01/projectgroup02", varParentPath: "org/org01/projectgroup01/projectgroup02",
secrets: []*types.Secret{ secrets: []*csapi.Secret{
&types.Secret{ &csapi.Secret{
Secret: &types.Secret{
Name: "secret01", Name: "secret01",
Parent: types.Parent{
Path: "org/org01/projectgroup01/projectgroup02/project01",
}, },
ParentPath: "org/org01/projectgroup01/projectgroup02/project01",
}, },
}, },
out: nil, out: nil,
@ -190,25 +191,25 @@ func TestGetVarValueMatchingSecret(t *testing.T) {
SecretVar: "secretvar01", SecretVar: "secretvar01",
}, },
varParentPath: "org/org01/projectgroup01/projectgroup02", varParentPath: "org/org01/projectgroup01/projectgroup02",
secrets: []*types.Secret{ secrets: []*csapi.Secret{
&types.Secret{ &csapi.Secret{
Secret: &types.Secret{
Name: "secret01", Name: "secret01",
Parent: types.Parent{
Path: "org/org01/projectgroup01/projectgroup02/project01",
}, },
ParentPath: "org/org01/projectgroup01/projectgroup02/project01",
}, },
&types.Secret{ &csapi.Secret{
Secret: &types.Secret{
Name: "secret01", Name: "secret01",
Parent: types.Parent{ },
Path: "org/org01/projectgroup01/projectgroup02", ParentPath: "org/org01/projectgroup01/projectgroup02",
}, },
}, },
}, out: &csapi.Secret{
out: &types.Secret{ Secret: &types.Secret{
Name: "secret01", Name: "secret01",
Parent: types.Parent{
Path: "org/org01/projectgroup01/projectgroup02",
}, },
ParentPath: "org/org01/projectgroup01/projectgroup02",
}, },
}, },
{ {
@ -218,19 +219,19 @@ func TestGetVarValueMatchingSecret(t *testing.T) {
SecretVar: "secretvar01", SecretVar: "secretvar01",
}, },
varParentPath: "org/org01/projectgroup01/projectgroup02", varParentPath: "org/org01/projectgroup01/projectgroup02",
secrets: []*types.Secret{ secrets: []*csapi.Secret{
&types.Secret{ &csapi.Secret{
Secret: &types.Secret{
Name: "secret01", Name: "secret01",
Parent: types.Parent{ },
Path: "org/org01/projectgroup01", ParentPath: "org/org01/projectgroup01",
}, },
}, },
}, out: &csapi.Secret{
out: &types.Secret{ Secret: &types.Secret{
Name: "secret01", Name: "secret01",
Parent: types.Parent{
Path: "org/org01/projectgroup01",
}, },
ParentPath: "org/org01/projectgroup01",
}, },
}, },
{ {
@ -240,33 +241,33 @@ func TestGetVarValueMatchingSecret(t *testing.T) {
SecretVar: "secretvar01", SecretVar: "secretvar01",
}, },
varParentPath: "org/org01/projectgroup01/projectgroup02", varParentPath: "org/org01/projectgroup01/projectgroup02",
secrets: []*types.Secret{ secrets: []*csapi.Secret{
// secrets must be in depth (from leaves to root) order as returned by the // secrets must be in depth (from leaves to root) order as returned by the
// configstore apis // configstore apis
&types.Secret{ &csapi.Secret{
Secret: &types.Secret{
Name: "secret01", Name: "secret01",
Parent: types.Parent{
Path: "org/org01/projectgroup01/projectgroup02/project01",
}, },
ParentPath: "org/org01/projectgroup01/projectgroup02/project01",
}, },
&types.Secret{ &csapi.Secret{
Secret: &types.Secret{
Name: "secret01", Name: "secret01",
Parent: types.Parent{
Path: "org/org01/projectgroup01/projectgroup02",
}, },
ParentPath: "org/org01/projectgroup01/projectgroup02",
}, },
&types.Secret{ &csapi.Secret{
Secret: &types.Secret{
Name: "secret01", Name: "secret01",
Parent: types.Parent{ },
Path: "org/org01/projectgroup01", ParentPath: "org/org01/projectgroup01",
}, },
}, },
}, out: &csapi.Secret{
out: &types.Secret{ Secret: &types.Secret{
Name: "secret01", Name: "secret01",
Parent: types.Parent{
Path: "org/org01/projectgroup01/projectgroup02",
}, },
ParentPath: "org/org01/projectgroup01/projectgroup02",
}, },
}, },
} }

View File

@ -217,7 +217,7 @@ func (h *webhooksHandler) handleWebhook(r *http.Request) (int, string, error) {
continue continue
} }
// get the secret value referenced by the variable, it must be a secret at the same level or a lower level // get the secret value referenced by the variable, it must be a secret at the same level or a lower level
secret := common.GetVarValueMatchingSecret(varval, pvar.Parent.Path, secrets) secret := common.GetVarValueMatchingSecret(varval, pvar.ParentPath, secrets)
h.log.Infof("secret: %v", util.Dump(secret)) h.log.Infof("secret: %v", util.Dump(secret))
if secret != nil { if secret != nil {
varValue, ok := secret.Data[varval.SecretVar] varValue, ok := secret.Data[varval.SecretVar]

View File

@ -36,9 +36,6 @@ const (
type Parent struct { type Parent struct {
Type ConfigType `json:"type,omitempty"` Type ConfigType `json:"type,omitempty"`
ID string `json:"id,omitempty"` ID string `json:"id,omitempty"`
// fields the is only used in api response and shoukd be empty when saved in the store
Path string `json:"path,omitempty"`
} }
type User struct { type User struct {