Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a route to only update a redactor's enabled status #814

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions kotsadm/pkg/apiserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func Start() {
r.Path("/api/v1/redact/spec/{slug}").Methods("OPTIONS", "GET").HandlerFunc(handlers.GetRedactMetadataAndYaml)
r.Path("/api/v1/redact/spec/{slug}").Methods("POST").HandlerFunc(handlers.SetRedactMetadataAndYaml)
r.Path("/api/v1/redact/spec/{slug}").Methods("DELETE").HandlerFunc(handlers.DeleteRedact)
r.Path("/api/v1/redact/enabled/{slug}").Methods("POST").HandlerFunc(handlers.SetRedactEnabled)

r.PathPrefix("/api/v1/kots/").Methods("OPTIONS").HandlerFunc(handlers.CORS)
r.PathPrefix("/api/v1/kots/").Methods("HEAD", "GET", "POST", "PUT", "DELETE").HandlerFunc(handlers.NodeProxy(upstream))
Expand Down
63 changes: 53 additions & 10 deletions kotsadm/pkg/handlers/redact.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/replicatedhq/kots/kotsadm/pkg/logger"
"github.com/replicatedhq/kots/kotsadm/pkg/redact"
"github.com/replicatedhq/kots/kotsadm/pkg/session"
"github.com/replicatedhq/kots/pkg/util"
)

type UpdateRedactRequest struct {
Expand Down Expand Up @@ -51,6 +50,10 @@ type PostRedactorMetadata struct {
Redactor string `json:"redactor"`
}

type PostRedactorEnabledMetadata struct {
Enabled bool `json:"enabled"`
}

func UpdateRedact(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "content-type, origin, accept, authorization")
Expand Down Expand Up @@ -311,17 +314,9 @@ func SetRedactMetadataAndYaml(w http.ResponseWriter, r *http.Request) {
return
}

marshalled, err := util.MarshalIndent(2, newRedactor.Redact)
if err != nil {
logger.Error(err)
metadataResponse.Error = "failed to marshal redactor"
JSON(w, http.StatusInternalServerError, metadataResponse)
return
}

metadataResponse.Success = true
metadataResponse.Metadata = newRedactor.Metadata
metadataResponse.Redactor = string(marshalled)
metadataResponse.Redactor = newRedactor.Redact
JSON(w, http.StatusOK, metadataResponse)
return
}
Expand Down Expand Up @@ -353,3 +348,51 @@ func DeleteRedact(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
return
}

func SetRedactEnabled(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "content-type, origin, accept, authorization")

metadataResponse := GetRedactorResponse{
Success: false,
}

sess, err := session.Parse(r.Header.Get("Authorization"))
if err != nil {
logger.Error(err)
metadataResponse.Error = "failed to parse authorization header"
JSON(w, 401, metadataResponse)
return
}

// we don't currently have roles, all valid tokens are valid sessions
if sess == nil || sess.ID == "" {
metadataResponse.Error = "no session in auth header"
JSON(w, 401, metadataResponse)
return
}

redactorSlug := mux.Vars(r)["slug"]

updateRedactRequest := PostRedactorEnabledMetadata{}
if err := json.NewDecoder(r.Body).Decode(&updateRedactRequest); err != nil {
logger.Error(err)
metadataResponse.Error = "failed to decode request body"
JSON(w, 400, metadataResponse)
return
}

updatedRedactor, err := redact.SetRedactEnabled(redactorSlug, updateRedactRequest.Enabled)
if err != nil {
logger.Error(err)
metadataResponse.Error = "failed to update redactor status"
JSON(w, 400, metadataResponse)
return
}

metadataResponse.Success = true
metadataResponse.Metadata = updatedRedactor.Metadata
metadataResponse.Redactor = updatedRedactor.Redact
JSON(w, http.StatusOK, metadataResponse)
return
}
58 changes: 52 additions & 6 deletions kotsadm/pkg/redact/redact.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type RedactorMetadata struct {
func GetRedactSpec() (string, string, error) {
configMap, errstr, err := getConfigmap()
if err != nil || configMap == nil {
return "", errstr, err
return "", errstr, errors.Wrap(err, "get redactors configmap")
}

return getRedactSpec(configMap)
Expand All @@ -66,7 +66,7 @@ func getRedactSpec(configMap *v1.ConfigMap) (string, string, error) {
func GetRedact() (*v1beta1.Redactor, error) {
configmap, _, err := getConfigmap()
if err != nil {
return nil, err
return nil, errors.Wrap(err, "get redactors configmap")
}
if configmap == nil {
return nil, nil
Expand Down Expand Up @@ -118,7 +118,7 @@ func GetRedactBySlug(slug string) (*RedactorMetadata, error) {
return nil, err
}
if configmap == nil {
return nil, fmt.Errorf("configmap not found")
return nil, errors.Wrap(err, "get redactors configmap")
}

redactString, ok := configmap.Data[slug]
Expand Down Expand Up @@ -149,7 +149,7 @@ func SetRedactSpec(spec string) (string, error) {

configMap, errMsg, err := getConfigmap()
if err != nil {
return errMsg, err
return errMsg, errors.Wrap(err, "get redactors configmap")
}

newMap, err := splitRedactors(spec, configMap.Data)
Expand All @@ -169,7 +169,7 @@ func SetRedactSpec(spec string) (string, error) {
func SetRedactYaml(slug, description string, enabled, newRedact bool, yamlBytes []byte) (*RedactorMetadata, error) {
configMap, _, err := getConfigmap()
if err != nil {
return nil, err
return nil, errors.Wrap(err, "get redactors configmap")
}

newData, redactorEntry, err := setRedactYaml(slug, description, enabled, newRedact, time.Now(), yamlBytes, configMap.Data)
Expand All @@ -186,6 +186,52 @@ func SetRedactYaml(slug, description string, enabled, newRedact bool, yamlBytes
return redactorEntry, nil
}

// sets whether an individual redactor is enabled
func SetRedactEnabled(slug string, enabled bool) (*RedactorMetadata, error) {
configMap, _, err := getConfigmap()
if err != nil {
return nil, errors.Wrap(err, "get redactors configmap")
}

newData, redactorEntry, err := setRedactEnabled(slug, enabled, time.Now(), configMap.Data)
if err != nil {
return nil, err
sgalsaleh marked this conversation as resolved.
Show resolved Hide resolved
}

configMap.Data = newData

_, err = writeConfigmap(configMap)
if err != nil {
return nil, errors.Wrapf(err, "write configMap with updated redact")
}
return redactorEntry, nil
}

func setRedactEnabled(slug string, enabled bool, currentTime time.Time, data map[string]string) (map[string]string, *RedactorMetadata, error) {
redactorEntry := RedactorMetadata{}
redactString, ok := data[slug]
if !ok {
return nil, nil, fmt.Errorf("redactor %s not found", slug)
}

// unmarshal existing redactor
err := json.Unmarshal([]byte(redactString), &redactorEntry)
if err != nil {
return nil, nil, errors.Wrapf(err, "unable to parse redactor %s", slug)
}

redactorEntry.Metadata.Enabled = enabled
redactorEntry.Metadata.Updated = currentTime

jsonBytes, err := json.Marshal(redactorEntry)
if err != nil {
return nil, nil, errors.Wrapf(err, "unable to marshal redactor %s", slug)
}

data[slug] = string(jsonBytes)
return data, &redactorEntry, nil
}

func setRedactYaml(slug, description string, enabled, newRedact bool, currentTime time.Time, yamlBytes []byte, data map[string]string) (map[string]string, *RedactorMetadata, error) {
// parse yaml as redactor
newRedactorSpec, err := parseRedact(yamlBytes)
Expand Down Expand Up @@ -266,7 +312,7 @@ func setRedactYaml(slug, description string, enabled, newRedact bool, currentTim
func DeleteRedact(slug string) error {
configMap, _, err := getConfigmap()
if err != nil {
return err
return errors.Wrap(err, "get redactors configmap")
}

delete(configMap.Data, slug)
Expand Down
95 changes: 95 additions & 0 deletions kotsadm/pkg/redact/redact_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -419,3 +419,98 @@ spec: {}`,
})
}
}

func Test_setRedactEnabled(t *testing.T) {
previousTime, err := time.Parse(time.RFC3339, "2010-06-15T14:26:10.721619-04:00")
if err != nil {
panic(err)
}

testTime, err := time.Parse(time.RFC3339, "2020-06-15T14:26:10.721619-04:00")
if err != nil {
panic(err)
}

type args struct {
slug string
enabled bool
data map[string]string
}
tests := []struct {
name string
args args
newMap map[string]string
newMetadata *RedactorMetadata
expectedSlug string
}{
{
name: "update existing redact",
args: args{
slug: "update-redact",
enabled: false,
data: map[string]string{
"update-redact": `{"metadata":{"name":"update redact","slug":"update-redact","createdAt":"2010-06-15T14:26:10.721619-04:00","updatedAt":"2010-06-15T14:26:10.721619-04:00","enabled":true,"description":"a description"},"redact":"kind: Redactor\napiVersion: troubleshoot.replicated.com/v1beta1\nmetadata:\n name: update redact"}`,
"leave-untouched": `other keys should not be modified`,
},
},
newMap: map[string]string{
"update-redact": `{"metadata":{"name":"update redact","slug":"update-redact","createdAt":"2010-06-15T14:26:10.721619-04:00","updatedAt":"2020-06-15T14:26:10.721619-04:00","enabled":false,"description":"a description"},"redact":"kind: Redactor\napiVersion: troubleshoot.replicated.com/v1beta1\nmetadata:\n name: update redact"}`,
"leave-untouched": `other keys should not be modified`,
},
newMetadata: &RedactorMetadata{
Redact: `kind: Redactor
apiVersion: troubleshoot.replicated.com/v1beta1
metadata:
name: update redact`,
Metadata: RedactorList{
Name: "update redact",
Slug: "update-redact",
Enabled: false,
Description: "a description",
Created: previousTime,
Updated: testTime,
},
},
},
{
name: "updated time changes even if enabled does not",
args: args{
slug: "update-redact",
enabled: true,
data: map[string]string{
"update-redact": `{"metadata":{"name":"update redact","slug":"update-redact","createdAt":"2010-06-15T14:26:10.721619-04:00","updatedAt":"2010-06-15T14:26:10.721619-04:00","enabled":true,"description":"a description"},"redact":"kind: Redactor\napiVersion: troubleshoot.replicated.com/v1beta1\nmetadata:\n name: update redact"}`,
"leave-untouched": `other keys should not be modified`,
},
},
newMap: map[string]string{
"update-redact": `{"metadata":{"name":"update redact","slug":"update-redact","createdAt":"2010-06-15T14:26:10.721619-04:00","updatedAt":"2020-06-15T14:26:10.721619-04:00","enabled":true,"description":"a description"},"redact":"kind: Redactor\napiVersion: troubleshoot.replicated.com/v1beta1\nmetadata:\n name: update redact"}`,
"leave-untouched": `other keys should not be modified`,
},
newMetadata: &RedactorMetadata{
Redact: `kind: Redactor
apiVersion: troubleshoot.replicated.com/v1beta1
metadata:
name: update redact`,
Metadata: RedactorList{
Name: "update redact",
Slug: "update-redact",
Enabled: true,
Description: "a description",
Created: previousTime,
Updated: testTime,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := require.New(t)

newMap, newMetadata, err := setRedactEnabled(tt.args.slug, tt.args.enabled, testTime, tt.args.data)
req.NoError(err)

req.Equal(tt.newMap, newMap)
req.Equal(tt.newMetadata, newMetadata)
})
}
}