Skip to content
This repository has been archived by the owner on Mar 24, 2023. It is now read-only.

Commit

Permalink
Delete base resources from UI (#695)
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob0h authored Nov 12, 2018
1 parent b4d1c67 commit 776142a
Show file tree
Hide file tree
Showing 23 changed files with 483 additions and 70 deletions.
17 changes: 16 additions & 1 deletion integration/update/basic/input/.ship/state.json
Original file line number Diff line number Diff line change
@@ -1 +1,16 @@
{"v1":{"config":{},"helmValues":"# Default values for basic.\n# This is a YAML-formatted file.\n# Declare variables to be passed into your templates.\n\nreplicaCount: 5\n\nimage:\n repository: nginx\n tag: stable\n pullPolicy: IfNotPresent\n\nservice:\n type: ClusterIP\n port: 80\n\ningress:\n enabled: false\n annotations: {}\n # kubernetes.io/ingress.class: nginx\n # kubernetes.io/tls-acme: \"true\"\n path: /\n hosts:\n - chart-example.local\n tls: []\n # - secretName: chart-example-tls\n # hosts:\n # - chart-example.local\n\nresources: {}\n # We usually recommend not to specify default resources and to leave this as a conscious\n # choice for the user. This also increases chances charts run on environments with little\n # resources, such as Minikube. If you do want to specify resources, uncomment the following\n # lines, adjust them as necessary, and remove the curly braces after 'resources:'.\n # limits:\n # cpu: 100m\n # memory: 128Mi\n # requests:\n # cpu: 100m\n # memory: 128Mi\n\nnodeSelector: {}\n\ntolerations: []\n\naffinity: {}\n","kustomize":{"overlays":{"ship":{"patches":{"/templates/deployment.yaml":"--- \napiVersion: apps/v1beta2\nkind: Deployment\nmetadata:\n name: 'basic'\n"}}}},"upstream":"github.com/replicatedhq/test-charts/basic"}}
{
"v1": {
"config": {},
"helmValues": "# Default values for basic.\n# This is a YAML-formatted file.\n# Declare variables to be passed into your templates.\n\nreplicaCount: 5\n\nimage:\n repository: nginx\n tag: stable\n pullPolicy: IfNotPresent\n\nservice:\n type: ClusterIP\n port: 80\n\ningress:\n enabled: false\n annotations: {}\n # kubernetes.io/ingress.class: nginx\n # kubernetes.io/tls-acme: \"true\"\n path: /\n hosts:\n - chart-example.local\n tls: []\n # - secretName: chart-example-tls\n # hosts:\n # - chart-example.local\n\nresources: {}\n # We usually recommend not to specify default resources and to leave this as a conscious\n # choice for the user. This also increases chances charts run on environments with little\n # resources, such as Minikube. If you do want to specify resources, uncomment the following\n # lines, adjust them as necessary, and remove the curly braces after 'resources:'.\n # limits:\n # cpu: 100m\n # memory: 128Mi\n # requests:\n # cpu: 100m\n # memory: 128Mi\n\nnodeSelector: {}\n\ntolerations: []\n\naffinity: {}\n",
"kustomize": {
"overlays": {
"ship": {
"patches": {
"/templates/deployment.yaml": "--- \napiVersion: apps/v1beta2\nkind: Deployment\nmetadata:\n name: 'basic'\n"
}
}
}
},
"upstream": "github.com/replicatedhq/test-charts/basic"
}
}
28 changes: 28 additions & 0 deletions integration/update/excluded-basic/expected/.ship/state.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"v1": {
"config": {},
"helmValues": "affinity: {}\nimage:\n pullPolicy: IfNotPresent\n repository: nginx\n tag: stable\ningress:\n annotations: {}\n enabled: false\n hosts:\n - chart-example.local\n path: /\n tls: []\nnodeSelector: {}\nreplicaCount: 5\nresources: {}\nservice:\n port: 80\n type: ClusterIP\ntolerations: []\n",
"releaseName": "basic",
"helmValuesDefaults": "# Default values for basic.\n# This is a YAML-formatted file.\n# Declare variables to be passed into your templates.\n\nreplicaCount: 1\n\nimage:\n repository: nginx\n tag: stable\n pullPolicy: IfNotPresent\n\nservice:\n type: ClusterIP\n port: 80\n\ningress:\n enabled: false\n annotations: {}\n # kubernetes.io/ingress.class: nginx\n # kubernetes.io/tls-acme: \"true\"\n path: /\n hosts:\n - chart-example.local\n tls: []\n # - secretName: chart-example-tls\n # hosts:\n # - chart-example.local\n\nresources: {}\n # We usually recommend not to specify default resources and to leave this as a conscious\n # choice for the user. This also increases chances charts run on environments with little\n # resources, such as Minikube. If you do want to specify resources, uncomment the following\n # lines, adjust them as necessary, and remove the curly braces after 'resources:'.\n # limits:\n # cpu: 100m\n # memory: 128Mi\n # requests:\n # cpu: 100m\n # memory: 128Mi\n\nnodeSelector: {}\n\ntolerations: []\n\naffinity: {}\n",
"kustomize": {
"overlays": {
"ship": {
"excludedBases": [
"service.yaml"
],
"patches": {
"/templates/deployment.yaml": "--- \napiVersion: apps/v1beta2\nkind: Deployment\nmetadata:\n name: 'basic'\n"
}
}
}
},
"upstream": "github.com/replicatedhq/test-charts/basic",
"metadata": {
"applicationType": "helm",
"name": "basic",
"releaseNotes": "Update README.md",
"version": "0.1.0"
},
"contentSHA": "94d255c48a20929dbfbe341109a7ab86dae1ecfab3b8f01151bb36a2ebea7bbe"
}
}
42 changes: 42 additions & 0 deletions integration/update/excluded-basic/expected/base/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
# Source: basic/templates/deployment.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: basic
labels:
app: basic
chart: basic-0.1.0
release: basic
heritage: Tiller
spec:
replicas: 5
selector:
matchLabels:
app: basic
release: basic
template:
metadata:
labels:
app: basic
release: basic
spec:
containers:
- name: basic
image: "nginx:stable"
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
resources:
{}

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
kind: ""
apiversion: ""
resources:
- deployment.yaml
21 changes: 21 additions & 0 deletions integration/update/excluded-basic/expected/base/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
# Source: basic/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: basic
labels:
app: basic
chart: basic-0.1.0
release: basic
heritage: Tiller
spec:
type: ClusterIP
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app: basic
release: basic
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: ""
apiversion: ""
bases:
- ../../base
patchesStrategicMerge:
- templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: 'basic'
38 changes: 38 additions & 0 deletions integration/update/excluded-basic/expected/rendered.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
apiVersion: apps/v1beta2
kind: Deployment
metadata:
labels:
app: basic
chart: basic-0.1.0
heritage: Tiller
release: basic
name: basic
spec:
replicas: 5
selector:
matchLabels:
app: basic
release: basic
template:
metadata:
labels:
app: basic
release: basic
spec:
containers:
- image: nginx:stable
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /
port: http
name: basic
ports:
- containerPort: 80
name: http
protocol: TCP
readinessProbe:
httpGet:
path: /
port: http
resources: {}
19 changes: 19 additions & 0 deletions integration/update/excluded-basic/input/.ship/state.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"v1": {
"config": {},
"helmValues": "# Default values for basic.\n# This is a YAML-formatted file.\n# Declare variables to be passed into your templates.\n\nreplicaCount: 5\n\nimage:\n repository: nginx\n tag: stable\n pullPolicy: IfNotPresent\n\nservice:\n type: ClusterIP\n port: 80\n\ningress:\n enabled: false\n annotations: {}\n # kubernetes.io/ingress.class: nginx\n # kubernetes.io/tls-acme: \"true\"\n path: /\n hosts:\n - chart-example.local\n tls: []\n # - secretName: chart-example-tls\n # hosts:\n # - chart-example.local\n\nresources: {}\n # We usually recommend not to specify default resources and to leave this as a conscious\n # choice for the user. This also increases chances charts run on environments with little\n # resources, such as Minikube. If you do want to specify resources, uncomment the following\n # lines, adjust them as necessary, and remove the curly braces after 'resources:'.\n # limits:\n # cpu: 100m\n # memory: 128Mi\n # requests:\n # cpu: 100m\n # memory: 128Mi\n\nnodeSelector: {}\n\ntolerations: []\n\naffinity: {}\n",
"kustomize": {
"overlays": {
"ship": {
"excludedBases": [
"service.yaml"
],
"patches": {
"/templates/deployment.yaml": "--- \napiVersion: apps/v1beta2\nkind: Deployment\nmetadata:\n name: 'basic'\n"
}
}
}
},
"upstream": "github.com/replicatedhq/test-charts/basic"
}
}
2 changes: 2 additions & 0 deletions integration/update/excluded-basic/metadata.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
args: ["--prefer-git"]
skip_cleanup: false
1 change: 1 addition & 0 deletions pkg/filetree/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ type Node struct {
Path string `json:"path" yaml:"path"`
HasOverlay bool `json:"hasOverlay" yaml:"hasOverlay"`
IsSupported bool `json:"isSupported" yaml:"isSupported"`
IsExcluded bool `json:"isExcluded" yaml:"isExcluded"`
}
18 changes: 13 additions & 5 deletions pkg/filetree/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,12 @@ func NewLoader(
}

type aferoLoader struct {
Logger log.Logger
FS afero.Afero
StateManager state.Manager
patches map[string]string
resources map[string]string
Logger log.Logger
FS afero.Afero
StateManager state.Manager
excludedBases map[string]string
patches map[string]string
resources map[string]string
}

func (a *aferoLoader) loadShipOverlay() error {
Expand All @@ -64,6 +65,11 @@ func (a *aferoLoader) loadShipOverlay() error {
}

shipOverlay := kustomize.Ship()
baseMap := make(map[string]string)
for _, base := range shipOverlay.ExcludedBases {
baseMap[base] = base
}
a.excludedBases = baseMap
a.patches = shipOverlay.Patches
a.resources = shipOverlay.Resources
return nil
Expand Down Expand Up @@ -155,11 +161,13 @@ func (a *aferoLoader) loadTree(fs afero.Afero, current Node, files []os.FileInfo
return current, errors.Wrapf(err, "read file %s", file.Name())
}

_, exists := a.excludedBases[filePath]
return a.loadTree(fs, current.withChild(Node{
Name: file.Name(),
Path: filePath,
HasOverlay: hasOverlay,
IsSupported: isSupported(fileB),
IsExcluded: exists,
}), rest)
}

Expand Down
1 change: 1 addition & 0 deletions pkg/lifecycle/daemon/routes_navcycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func (d *NavcycleRoutes) Register(group *gin.RouterGroup, release *api.Release)
kustom.POST("patch", d.createOrMergePatch)
kustom.DELETE("patch", d.deletePatch)
kustom.DELETE("resource", d.deleteResource)
kustom.DELETE("base", d.deleteBase)
kustom.POST("apply", d.applyPatch)

conf := v1.Group("/config")
Expand Down
57 changes: 57 additions & 0 deletions pkg/lifecycle/daemon/routes_navcycle_kustomize.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ func (d *NavcycleRoutes) applyPatch(c *gin.Context) {
if err := c.BindJSON(&request); err != nil {
level.Error(d.Logger).Log("event", "unmarshal request body failed", "err", err)
c.AbortWithError(500, errors.New("internal_server_error"))
return
}

debug.Log("event", "getKustomizationStep")
Expand All @@ -221,6 +222,7 @@ func (d *NavcycleRoutes) applyPatch(c *gin.Context) {
if err != nil {
level.Error(d.Logger).Log("event", "failed to merge patch with base", "err", err)
c.AbortWithError(500, errors.New("internal_server_error"))
return
}

c.JSON(200, map[string]interface{}{
Expand All @@ -242,6 +244,7 @@ func (d *NavcycleRoutes) createOrMergePatch(c *gin.Context) {
if err := c.BindJSON(&request); err != nil {
level.Error(d.Logger).Log("event", "unmarshal request body failed", "err", err)
c.AbortWithError(500, errors.New("internal_server_error"))
return
}

var stringPath []string
Expand All @@ -254,6 +257,7 @@ func (d *NavcycleRoutes) createOrMergePatch(c *gin.Context) {
default:
level.Error(d.Logger).Log("event", "invalid path provided")
c.AbortWithError(500, errors.New("internal_server_error"))
return
}
}

Expand All @@ -267,27 +271,31 @@ func (d *NavcycleRoutes) createOrMergePatch(c *gin.Context) {
if err != nil {
level.Error(d.Logger).Log("event", "failed to read original file", "err", err)
c.AbortWithError(500, errors.New("internal_server_error"))
return
}

debug.Log("event", "patcher.modifyField")
modified, err := d.Patcher.ModifyField(original, stringPath)
if err != nil {
level.Error(d.Logger).Log("event", "modify field", "err", err)
c.AbortWithError(500, errors.New("internal_server_error"))
return
}

debug.Log("event", "patcher.CreatePatch")
patch, err := d.Patcher.CreateTwoWayMergePatch(original, modified)
if err != nil {
level.Error(d.Logger).Log("event", "create two way merge patch", "err", err)
c.AbortWithError(500, errors.New("internal_server_error"))
return
}

if len(request.Current) > 0 {
out, err := d.Patcher.MergePatches([]byte(request.Current), stringPath, *step.Kustomize, request.Resource)
if err != nil {
level.Error(d.Logger).Log("event", "merge current and new patch", "err", err)
c.AbortWithError(500, errors.New("internal_server_error"))
return
}
c.JSON(200, map[string]interface{}{
"patch": string(out),
Expand All @@ -298,6 +306,53 @@ func (d *NavcycleRoutes) createOrMergePatch(c *gin.Context) {
})
}
}

func (d *NavcycleRoutes) deleteBase(c *gin.Context) {
debug := level.Debug(log.With(d.Logger, "struct", "daemon", "handler", "deleteBase"))
pathQueryParam := c.Query("path")
if pathQueryParam == "" {
c.AbortWithError(http.StatusBadRequest, errors.New("bad delete request"))
return
}

currentState, err := d.StateManager.TryLoad()
if err != nil {
c.AbortWithError(http.StatusInternalServerError, errors.Wrap(err, "delete base"))
return
}

kustomize := currentState.CurrentKustomize()
if kustomize == nil {
kustomize = &state.Kustomize{}
}

shipOverlay := kustomize.Ship()
for _, base := range shipOverlay.ExcludedBases {
if base == pathQueryParam {
debug.Log("event", "base", pathQueryParam, "exists in excluded")
c.AbortWithError(http.StatusInternalServerError, errors.New("internal_server_error"))
return
}
}
shipOverlay.ExcludedBases = append(shipOverlay.ExcludedBases, pathQueryParam)

if _, exists := shipOverlay.Patches[pathQueryParam]; exists {
delete(shipOverlay.Patches, pathQueryParam)
}

if kustomize.Overlays == nil {
kustomize.Overlays = map[string]state.Overlay{}
}
kustomize.Overlays["ship"] = shipOverlay

if err := d.StateManager.SaveKustomize(kustomize); err != nil {
c.AbortWithError(500, errors.Wrap(err, "delete base"))
return
}

c.JSON(200, map[string]string{"status": "success"})
}

func (d *NavcycleRoutes) deleteResource(c *gin.Context) {
debug := level.Debug(log.With(d.Logger, "struct", "daemon", "handler", "deleteResource"))
pathQueryParam := c.Query("path")
Expand All @@ -314,6 +369,7 @@ func (d *NavcycleRoutes) deleteResource(c *gin.Context) {
if err != nil {
level.Error(d.Logger).Log("event", "resource.delete.fail", "path", pathQueryParam, "err", err)
c.AbortWithError(500, errors.Wrap(err, "delete resource"))
return
}
c.JSON(200, map[string]string{"status": "success"})
}
Expand All @@ -334,6 +390,7 @@ func (d *NavcycleRoutes) deletePatch(c *gin.Context) {
if err != nil {
level.Error(d.Logger).Log("event", "resource.delete.fail", "path", pathQueryParam, "err", err)
c.AbortWithError(500, errors.Wrap(err, "delete resource"))
return
}

c.JSON(200, map[string]string{"status": "success"})
Expand Down
Loading

0 comments on commit 776142a

Please sign in to comment.