gateway: implement secret update

This commit is contained in:
Simone Gotti 2019-07-08 10:32:45 +02:00
parent 289e691a58
commit 34d36e9e24
4 changed files with 142 additions and 0 deletions

View File

@ -102,6 +102,61 @@ func (h *ActionHandler) CreateSecret(ctx context.Context, req *CreateSecretReque
return rs, nil return rs, nil
} }
type UpdateSecretRequest struct {
SecretName string
Name string
ParentType types.ConfigType
ParentRef string
Type types.SecretType
// internal secret
Data map[string]string
// external secret
SecretProviderID string
Path string
}
func (h *ActionHandler) UpdateSecret(ctx context.Context, req *UpdateSecretRequest) (*csapi.Secret, error) {
isVariableOwner, err := h.IsVariableOwner(ctx, req.ParentType, req.ParentRef)
if err != nil {
return nil, errors.Errorf("failed to determine ownership: %w", err)
}
if !isVariableOwner {
return nil, util.NewErrForbidden(errors.Errorf("user not authorized"))
}
if !util.ValidateName(req.Name) {
return nil, util.NewErrBadRequest(errors.Errorf("invalid secret name %q", req.Name))
}
s := &types.Secret{
Name: req.Name,
Type: req.Type,
Data: req.Data,
}
var resp *http.Response
var rs *csapi.Secret
switch req.ParentType {
case types.ConfigTypeProjectGroup:
h.log.Infof("updating project group secret")
rs, resp, err = h.configstoreClient.UpdateProjectGroupSecret(ctx, req.ParentRef, req.SecretName, s)
case types.ConfigTypeProject:
h.log.Infof("updating project secret")
rs, resp, err = h.configstoreClient.UpdateProjectSecret(ctx, req.ParentRef, req.SecretName, s)
}
if err != nil {
return nil, errors.Errorf("failed to update secret: %w", ErrFromRemote(resp, err))
}
h.log.Infof("secret %s updated, ID: %s", rs.Name, rs.ID)
return rs, nil
}
func (h *ActionHandler) DeleteSecret(ctx context.Context, parentType types.ConfigType, parentRef, name string) error { func (h *ActionHandler) DeleteSecret(ctx context.Context, parentType types.ConfigType, parentRef, name string) error {
isVariableOwner, err := h.IsVariableOwner(ctx, parentType, parentRef) isVariableOwner, err := h.IsVariableOwner(ctx, parentType, parentRef)
if err != nil { if err != nil {

View File

@ -172,6 +172,17 @@ func (c *Client) CreateProjectGroupSecret(ctx context.Context, projectGroupRef s
return secret, resp, err return secret, resp, err
} }
func (c *Client) UpdateProjectGroupSecret(ctx context.Context, projectGroupRef, secretName string, req *UpdateSecretRequest) (*SecretResponse, *http.Response, error) {
reqj, err := json.Marshal(req)
if err != nil {
return nil, nil, err
}
secret := new(SecretResponse)
resp, err := c.getParsedResponse(ctx, "PUT", path.Join("/projectgroups", url.PathEscape(projectGroupRef), "secrets", secretName), nil, jsonContent, bytes.NewReader(reqj), secret)
return secret, 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) {
return c.getResponse(ctx, "DELETE", path.Join("/projectgroups", url.PathEscape(projectGroupRef), "secrets", secretName), nil, jsonContent, nil) return c.getResponse(ctx, "DELETE", path.Join("/projectgroups", url.PathEscape(projectGroupRef), "secrets", secretName), nil, jsonContent, nil)
} }
@ -187,6 +198,17 @@ func (c *Client) CreateProjectSecret(ctx context.Context, projectRef string, req
return secret, resp, err return secret, resp, err
} }
func (c *Client) UpdateProjectSecret(ctx context.Context, projectRef, secretName string, req *UpdateSecretRequest) (*SecretResponse, *http.Response, error) {
reqj, err := json.Marshal(req)
if err != nil {
return nil, nil, err
}
secret := new(SecretResponse)
resp, err := c.getParsedResponse(ctx, "PUT", path.Join("/projects", url.PathEscape(projectRef), "secrets", secretName), nil, jsonContent, bytes.NewReader(reqj), secret)
return secret, resp, err
}
func (c *Client) DeleteProjectSecret(ctx context.Context, projectRef, secretName string) (*http.Response, error) { func (c *Client) DeleteProjectSecret(ctx context.Context, projectRef, secretName string) (*http.Response, error) {
return c.getResponse(ctx, "DELETE", path.Join("/projects", url.PathEscape(projectRef), "secrets", secretName), nil, jsonContent, nil) return c.getResponse(ctx, "DELETE", path.Join("/projects", url.PathEscape(projectRef), "secrets", secretName), nil, jsonContent, nil)
} }

View File

@ -133,6 +133,68 @@ func (h *CreateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
return return
} }
res := createSecretResponse(cssecret)
if err := httpResponse(w, http.StatusCreated, res); err != nil {
h.log.Errorf("err: %+v", err)
}
}
type UpdateSecretRequest struct {
Name string `json:"name,omitempty"`
Type types.SecretType `json:"type,omitempty"`
// internal secret
Data map[string]string `json:"data,omitempty"`
// external secret
SecretProviderID string `json:"secret_provider_id,omitempty"`
Path string `json:"path,omitempty"`
}
type UpdateSecretHandler struct {
log *zap.SugaredLogger
ah *action.ActionHandler
}
func NewUpdateSecretHandler(logger *zap.Logger, ah *action.ActionHandler) *UpdateSecretHandler {
return &UpdateSecretHandler{log: logger.Sugar(), ah: ah}
}
func (h *UpdateSecretHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
secretName := vars["secretname"]
parentType, parentRef, err := GetConfigTypeRef(r)
if httpError(w, err) {
h.log.Errorf("err: %+v", err)
return
}
var req UpdateSecretRequest
d := json.NewDecoder(r.Body)
if err := d.Decode(&req); err != nil {
httpError(w, util.NewErrBadRequest(err))
return
}
areq := &action.UpdateSecretRequest{
SecretName: secretName,
Name: req.Name,
ParentType: parentType,
ParentRef: parentRef,
Type: req.Type,
Data: req.Data,
SecretProviderID: req.SecretProviderID,
Path: req.Path,
}
cssecret, err := h.ah.UpdateSecret(ctx, areq)
if httpError(w, err) {
h.log.Errorf("err: %+v", err)
return
}
res := createSecretResponse(cssecret) res := createSecretResponse(cssecret)
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

@ -161,6 +161,7 @@ func (g *Gateway) Run(ctx context.Context) error {
secretHandler := api.NewSecretHandler(logger, g.ah) secretHandler := api.NewSecretHandler(logger, g.ah)
createSecretHandler := api.NewCreateSecretHandler(logger, g.ah) createSecretHandler := api.NewCreateSecretHandler(logger, g.ah)
updateSecretHandler := api.NewUpdateSecretHandler(logger, g.ah)
deleteSecretHandler := api.NewDeleteSecretHandler(logger, g.ah) deleteSecretHandler := api.NewDeleteSecretHandler(logger, g.ah)
variableHandler := api.NewVariableHandler(logger, g.ah) variableHandler := api.NewVariableHandler(logger, g.ah)
@ -246,6 +247,8 @@ func (g *Gateway) Run(ctx context.Context) error {
apirouter.Handle("/projects/{projectref}/secrets", authForcedHandler(secretHandler)).Methods("GET") apirouter.Handle("/projects/{projectref}/secrets", authForcedHandler(secretHandler)).Methods("GET")
apirouter.Handle("/projectgroups/{projectgroupref}/secrets", authForcedHandler(createSecretHandler)).Methods("POST") apirouter.Handle("/projectgroups/{projectgroupref}/secrets", authForcedHandler(createSecretHandler)).Methods("POST")
apirouter.Handle("/projects/{projectref}/secrets", authForcedHandler(createSecretHandler)).Methods("POST") apirouter.Handle("/projects/{projectref}/secrets", authForcedHandler(createSecretHandler)).Methods("POST")
apirouter.Handle("/projectgroups/{projectgroupref}/secrets/{secretname}", authForcedHandler(updateSecretHandler)).Methods("PUT")
apirouter.Handle("/projects/{projectref}/secrets/{secretname}", authForcedHandler(updateSecretHandler)).Methods("PUT")
apirouter.Handle("/projectgroups/{projectgroupref}/secrets/{secretname}", authForcedHandler(deleteSecretHandler)).Methods("DELETE") apirouter.Handle("/projectgroups/{projectgroupref}/secrets/{secretname}", authForcedHandler(deleteSecretHandler)).Methods("DELETE")
apirouter.Handle("/projects/{projectref}/secrets/{secretname}", authForcedHandler(deleteSecretHandler)).Methods("DELETE") apirouter.Handle("/projects/{projectref}/secrets/{secretname}", authForcedHandler(deleteSecretHandler)).Methods("DELETE")