mirror of
https://github.com/skooner-k8s/skooner.git
synced 2026-08-24 04:16:18 +00:00
Last minute cleanup. Improving docker build process
This commit is contained in:
+15
-11
@@ -1,23 +1,27 @@
|
||||
# THIS IS THE BASEIMAGE THAT ALL OTHER SERVICES ARE BUILT UPON
|
||||
# Stage 1 - the build react app
|
||||
FROM node:11.10.0-alpine as build-deps
|
||||
WORKDIR /usr/src/app
|
||||
COPY client/package.json client/package-lock.json ./
|
||||
RUN npm i
|
||||
|
||||
COPY client/ ./
|
||||
RUN npm run build
|
||||
|
||||
# Stage 2 - the production environment
|
||||
FROM node:11.10.0-alpine
|
||||
|
||||
RUN apk add --no-cache tini
|
||||
|
||||
ENV NODE_ENV production
|
||||
|
||||
RUN mkdir -p /usr/src/app
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
RUN chown -R node:node /usr/src/app/
|
||||
EXPOSE 4654
|
||||
|
||||
COPY server/package.json /usr/src/app/
|
||||
COPY server/package-lock.json /usr/src/app/
|
||||
RUN npm install --production
|
||||
COPY server/package.json server/package-lock.json ./
|
||||
RUN npm i --production
|
||||
|
||||
COPY client/build /usr/src/app/public
|
||||
COPY server /usr/src/app
|
||||
COPY --from=build-deps /usr/src/app/build /usr/src/app/public
|
||||
COPY /server ./
|
||||
|
||||
USER node
|
||||
|
||||
ENTRYPOINT ["/sbin/tini", "--", "node", "."]
|
||||
ENTRYPOINT ["/sbin/tini", "--", "node", "."]
|
||||
|
||||
@@ -109,3 +109,19 @@ K8dash relies heavily on [metrics-server](https://github.com/kubernetes-incubato
|
||||
|
||||
+ [Installing metrics-server](https://github.com/kubernetes-incubator/metrics-server)
|
||||
+ [Running metrics-server with kubeadm](https://medium.com/@waleedkhan91/how-to-configure-metrics-server-on-kubeadm-provisioned-kubernetes-cluster-f755a2ac43a2)
|
||||
|
||||
|
||||
# Development
|
||||
K8dash is made up of 2 parts. The server and the client.
|
||||
|
||||
### Server
|
||||
To run the server, run `npm i` from the `/server` directory to install dependencies and then `npm start` to run the server.
|
||||
The server is a simple express.js server that is primarily responsible for proxying requests to the Kubernetes api server.
|
||||
During development, the server will use whatever is configured in `~/.kube/config` to connect the desired cluster.
|
||||
|
||||
### Client
|
||||
For the client, move to the `/client` directory, run `npm i` and then `npm start`. The client is a React application with minimal other dependencies.
|
||||
|
||||
## License
|
||||
|
||||
[Apache License 2.0](https://raw.githubusercontent.com/herbrandson/k8dash/master/LICENSE)
|
||||
Generated
+86
-99
@@ -1029,14 +1029,14 @@
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "11.10.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-11.10.5.tgz",
|
||||
"integrity": "sha512-DuIRlQbX4K+d5I+GMnv+UfnGh+ist0RdlvOp+JZ7ePJ6KQONCFQv/gKYSU1ZzbVdFSUCKZOltjmpFAGGv5MdYA=="
|
||||
"version": "11.11.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.3.tgz",
|
||||
"integrity": "sha512-wp6IOGu1lxsfnrD+5mX6qwSwWuqsdkKKxTN4aQc4wByHAKZJf9/D4KXPQ1POUjEbnCP5LMggB0OEFNY9OTsMqg=="
|
||||
},
|
||||
"@types/q": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.1.tgz",
|
||||
"integrity": "sha512-eqz8c/0kwNi/OEHQfvIuJVLTst3in0e7uTKeuY+WL/zfKn0xVujOTp42bS/vUUokhK5P2BppLd9JXMOMHcgbjA=="
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz",
|
||||
"integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw=="
|
||||
},
|
||||
"@types/tapable": {
|
||||
"version": "1.0.2",
|
||||
@@ -1816,9 +1816,9 @@
|
||||
}
|
||||
},
|
||||
"async-each": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
|
||||
"integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0="
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.2.tgz",
|
||||
"integrity": "sha512-6xrbvN0MOBKSJDdonmSSz2OwFSgxRaVtBDes26mj9KIGtDo+g9xosFRSC+i1gQh2oAN/tQ62AI/pGZGQjVOiRg=="
|
||||
},
|
||||
"async-foreach": {
|
||||
"version": "0.1.3",
|
||||
@@ -1841,12 +1841,12 @@
|
||||
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
|
||||
},
|
||||
"autoprefixer": {
|
||||
"version": "9.4.10",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.4.10.tgz",
|
||||
"integrity": "sha512-XR8XZ09tUrrSzgSlys4+hy5r2/z4Jp7Ag3pHm31U4g/CTccYPOVe19AkaJ4ey/vRd1sfj+5TtuD6I0PXtutjvQ==",
|
||||
"version": "9.5.0",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.5.0.tgz",
|
||||
"integrity": "sha512-hMKcyHsZn5+qL6AUeP3c8OyuteZ4VaUlg+fWbyl8z7PqsKHF/Bf8/px3K6AT8aMzDkBo8Bc11245MM+itDBOxQ==",
|
||||
"requires": {
|
||||
"browserslist": "^4.4.2",
|
||||
"caniuse-lite": "^1.0.30000940",
|
||||
"caniuse-lite": "^1.0.30000947",
|
||||
"normalize-range": "^0.1.2",
|
||||
"num2fraction": "^1.2.2",
|
||||
"postcss": "^7.0.14",
|
||||
@@ -2644,13 +2644,13 @@
|
||||
}
|
||||
},
|
||||
"browserslist": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.4.2.tgz",
|
||||
"integrity": "sha512-ISS/AIAiHERJ3d45Fz0AVYKkgcy+F/eJHzKEvv1j0wwKGKD9T3BrwKr/5g45L+Y4XIK5PlTqefHciRFcfE1Jxg==",
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.5.0.tgz",
|
||||
"integrity": "sha512-92IS3knByY3wF7DDozdKwLxkvp23Ydn2O5L0qVwR1p/ioN7oIDl7d/eyPMc11rTVofT/6IbcdwP9eTId7orGZQ==",
|
||||
"requires": {
|
||||
"caniuse-lite": "^1.0.30000939",
|
||||
"electron-to-chromium": "^1.3.113",
|
||||
"node-releases": "^1.1.8"
|
||||
"caniuse-lite": "^1.0.30000948",
|
||||
"electron-to-chromium": "^1.3.116",
|
||||
"node-releases": "^1.1.10"
|
||||
}
|
||||
},
|
||||
"bser": {
|
||||
@@ -2814,9 +2814,9 @@
|
||||
}
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30000942",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000942.tgz",
|
||||
"integrity": "sha512-wLf+IhZUy2rfz48tc40OH7jHjXjnvDFEYqBHluINs/6MgzoNLPf25zhE4NOVzqxLKndf+hau81sAW0RcGHIaBQ=="
|
||||
"version": "1.0.30000949",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000949.tgz",
|
||||
"integrity": "sha512-jIF/jphmuJ7oAWmfYO0qAxRAvCa0zNquALO6Ykfe6qo8qwh882Cgcs+OWmm21L3x6nu4TVLFeEZ9/q6VuKCfSg=="
|
||||
},
|
||||
"capture-exit": {
|
||||
"version": "1.2.0",
|
||||
@@ -2859,9 +2859,9 @@
|
||||
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
|
||||
},
|
||||
"chartist": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/chartist/-/chartist-0.11.0.tgz",
|
||||
"integrity": "sha1-hLpeBUkNCW2T3PqTQ+vDHvajvSg="
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/chartist/-/chartist-0.10.1.tgz",
|
||||
"integrity": "sha1-PdUT1THfymt453f+BQDZx+ZAaTE="
|
||||
},
|
||||
"check-types": {
|
||||
"version": "7.4.0",
|
||||
@@ -5004,9 +5004,9 @@
|
||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
"version": "1.3.113",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz",
|
||||
"integrity": "sha512-De+lPAxEcpxvqPTyZAXELNpRZXABRxf+uL/rSykstQhzj/B0l1150G/ExIIxKc16lI89Hgz81J0BHAcbTqK49g=="
|
||||
"version": "1.3.116",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.116.tgz",
|
||||
"integrity": "sha512-NKwKAXzur5vFCZYBHpdWjTMO8QptNLNP80nItkSIgUOapPAo9Uia+RvkCaZJtO7fhQaVElSvBPWEc2ku6cKsPA=="
|
||||
},
|
||||
"elliptic": {
|
||||
"version": "6.4.1",
|
||||
@@ -5214,9 +5214,9 @@
|
||||
}
|
||||
},
|
||||
"eslint-scope": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.2.tgz",
|
||||
"integrity": "sha512-5q1+B/ogmHl8+paxtOKx38Z8LtWkVGuNt3+GQNErqwLl6ViNp/gdJGMCjZNxZ8j/VYjDNZ2Fo+eQc1TAVPIzbg==",
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
|
||||
"integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
|
||||
"requires": {
|
||||
"esrecurse": "^4.1.0",
|
||||
"estraverse": "^4.1.1"
|
||||
@@ -6231,12 +6231,12 @@
|
||||
}
|
||||
},
|
||||
"find-cache-dir": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.0.0.tgz",
|
||||
"integrity": "sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
|
||||
"integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
|
||||
"requires": {
|
||||
"commondir": "^1.0.1",
|
||||
"make-dir": "^1.0.0",
|
||||
"make-dir": "^2.0.0",
|
||||
"pkg-dir": "^3.0.0"
|
||||
}
|
||||
},
|
||||
@@ -9312,9 +9312,9 @@
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.5.10",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz",
|
||||
"integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==",
|
||||
"version": "0.5.11",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.11.tgz",
|
||||
"integrity": "sha512-//sajEx/fGL3iw6fltKMdPvy8kL3kJ2O3iuYlRoT3k9Kb4BjOoZ+BZzaNHeuaruSt+Kf3Zk9tnfAQg9/AJqUVQ==",
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
@@ -10190,17 +10190,18 @@
|
||||
}
|
||||
},
|
||||
"make-dir": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
|
||||
"integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
|
||||
"integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
|
||||
"requires": {
|
||||
"pify": "^3.0.0"
|
||||
"pify": "^4.0.1",
|
||||
"semver": "^5.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"pify": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
|
||||
"integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
|
||||
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -10530,9 +10531,9 @@
|
||||
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
|
||||
},
|
||||
"nan": {
|
||||
"version": "2.12.1",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz",
|
||||
"integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw=="
|
||||
"version": "2.13.1",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.13.1.tgz",
|
||||
"integrity": "sha512-I6YB/YEuDeUZMmhscXKxGgZlFnhsn5y0hgOZBadkzfTRrZBtJDZeg6eQf7PYMIEclwmorTKK8GztsyOUSVBREA=="
|
||||
},
|
||||
"nanomatch": {
|
||||
"version": "1.2.13",
|
||||
@@ -10683,9 +10684,9 @@
|
||||
}
|
||||
},
|
||||
"node-releases": {
|
||||
"version": "1.1.9",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.9.tgz",
|
||||
"integrity": "sha512-oic3GT4OtbWWKfRolz5Syw0Xus0KRFxeorLNj0s93ofX6PWyuzKjsiGxsCtWktBwwmTF6DdRRf2KreGqeOk5KA==",
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.11.tgz",
|
||||
"integrity": "sha512-8v1j5KfP+s5WOTa1spNUAOfreajQPN12JXbRR0oDE+YrJBQCXBnNqUDj27EKpPLOoSiU3tKi3xGPB+JaOdUEQQ==",
|
||||
"requires": {
|
||||
"semver": "^5.3.0"
|
||||
}
|
||||
@@ -15633,15 +15634,6 @@
|
||||
"prop-types": "^15.5.8"
|
||||
}
|
||||
},
|
||||
"react-chartjs-2": {
|
||||
"version": "2.7.4",
|
||||
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-2.7.4.tgz",
|
||||
"integrity": "sha512-lXTpBaDlk9rIMjRONjZd76dIUhEm3vOp2jOrJrsFG/UpFI5VqX8Xw83apVHTnUGJ968f8i/i/syLddls4NHy2g==",
|
||||
"requires": {
|
||||
"lodash": "^4.17.4",
|
||||
"prop-types": "^15.5.8"
|
||||
}
|
||||
},
|
||||
"react-dev-utils": {
|
||||
"version": "7.0.5",
|
||||
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-7.0.5.tgz",
|
||||
@@ -16379,9 +16371,9 @@
|
||||
"integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg=="
|
||||
},
|
||||
"regenerate-unicode-properties": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.0.1.tgz",
|
||||
"integrity": "sha512-HTjMafphaH5d5QDHuwW8Me6Hbc/GhXg8luNqTkPVwZ/oCZhnoifjWhGYsu2BzepMELTlbnoVcXvV0f+2uDDvoQ==",
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.0.2.tgz",
|
||||
"integrity": "sha512-SbA/iNrBUf6Pv2zU8Ekv1Qbhv92yxL4hiDa2siuxs4KKn4oOoMDHXjAf7+Nz9qinUQ46B1LcWEi/PhJfPWpZWQ==",
|
||||
"requires": {
|
||||
"regenerate": "^1.4.0"
|
||||
}
|
||||
@@ -16427,12 +16419,12 @@
|
||||
"integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw=="
|
||||
},
|
||||
"regexpu-core": {
|
||||
"version": "4.5.3",
|
||||
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.3.tgz",
|
||||
"integrity": "sha512-LON8666bTAlViVEPXMv65ZqiaR3rMNLz36PIaQ7D+er5snu93k0peR7FSvO0QteYbZ3GOkvfHKbGr/B1xDu9FA==",
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.4.tgz",
|
||||
"integrity": "sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==",
|
||||
"requires": {
|
||||
"regenerate": "^1.4.0",
|
||||
"regenerate-unicode-properties": "^8.0.1",
|
||||
"regenerate-unicode-properties": "^8.0.2",
|
||||
"regjsgen": "^0.5.0",
|
||||
"regjsparser": "^0.6.0",
|
||||
"unicode-match-property-ecmascript": "^1.0.4",
|
||||
@@ -18044,29 +18036,24 @@
|
||||
}
|
||||
},
|
||||
"terser": {
|
||||
"version": "3.16.1",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-3.16.1.tgz",
|
||||
"integrity": "sha512-JDJjgleBROeek2iBcSNzOHLKsB/MdDf+E/BOAJ0Tk9r7p9/fVobfv7LMJ/g/k3v9SXdmjZnIlFd5nfn/Rt0Xow==",
|
||||
"version": "3.17.0",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz",
|
||||
"integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==",
|
||||
"requires": {
|
||||
"commander": "~2.17.1",
|
||||
"commander": "^2.19.0",
|
||||
"source-map": "~0.6.1",
|
||||
"source-map-support": "~0.5.9"
|
||||
"source-map-support": "~0.5.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.17.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
|
||||
"integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg=="
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.5.10",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz",
|
||||
"integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==",
|
||||
"version": "0.5.11",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.11.tgz",
|
||||
"integrity": "sha512-//sajEx/fGL3iw6fltKMdPvy8kL3kJ2O3iuYlRoT3k9Kb4BjOoZ+BZzaNHeuaruSt+Kf3Zk9tnfAQg9/AJqUVQ==",
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
@@ -18327,19 +18314,14 @@
|
||||
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
|
||||
},
|
||||
"uglify-js": {
|
||||
"version": "3.4.9",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz",
|
||||
"integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==",
|
||||
"version": "3.4.10",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz",
|
||||
"integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==",
|
||||
"requires": {
|
||||
"commander": "~2.17.1",
|
||||
"commander": "~2.19.0",
|
||||
"source-map": "~0.6.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.17.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
|
||||
"integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg=="
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
@@ -18501,9 +18483,9 @@
|
||||
}
|
||||
},
|
||||
"upath": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/upath/-/upath-1.1.1.tgz",
|
||||
"integrity": "sha512-D0yetkpIOKiZQquxjM2Syvy48Y1DbZ0SWxgsZiwd9GCWRpc75vN8ytzem14WDSg+oiX6+Qt31FpiS/ExODCrLg=="
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz",
|
||||
"integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q=="
|
||||
},
|
||||
"upper-case": {
|
||||
"version": "1.1.3",
|
||||
@@ -18799,9 +18781,9 @@
|
||||
}
|
||||
},
|
||||
"eslint-scope": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.2.tgz",
|
||||
"integrity": "sha512-5q1+B/ogmHl8+paxtOKx38Z8LtWkVGuNt3+GQNErqwLl6ViNp/gdJGMCjZNxZ8j/VYjDNZ2Fo+eQc1TAVPIzbg==",
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
|
||||
"integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
|
||||
"requires": {
|
||||
"esrecurse": "^4.1.0",
|
||||
"estraverse": "^4.1.1"
|
||||
@@ -19207,15 +19189,20 @@
|
||||
}
|
||||
},
|
||||
"mem": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz",
|
||||
"integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mem/-/mem-4.2.0.tgz",
|
||||
"integrity": "sha512-5fJxa68urlY0Ir8ijatKa3eRz5lwXnRCTvo9+TbTGAuTFJOwpGcY0X05moBd0nW45965Njt4CDI2GFQoG8DvqA==",
|
||||
"requires": {
|
||||
"map-age-cleaner": "^0.1.1",
|
||||
"mimic-fn": "^1.0.0",
|
||||
"mimic-fn": "^2.0.0",
|
||||
"p-is-promise": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"mimic-fn": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.0.0.tgz",
|
||||
"integrity": "sha512-jbex9Yd/3lmICXwYT6gA/j2mNQGU48wCh/VzRd+/Y/PjYQtlg1gLMdZqvu9s/xH7qKvngxRObl56XZR609IMbA=="
|
||||
},
|
||||
"os-locale": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
|
||||
|
||||
+1
-2
@@ -3,14 +3,13 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"chartist": "^0.11.0",
|
||||
"chartist": "^0.10.1",
|
||||
"director": "^1.2.8",
|
||||
"lodash": "^4.17.11",
|
||||
"moment": "^2.24.0",
|
||||
"node-sass": "^4.11.0",
|
||||
"react": "^16.8.2",
|
||||
"react-chartist": "^0.13.3",
|
||||
"react-chartjs-2": "^2.7.4",
|
||||
"react-dom": "^16.8.2",
|
||||
"react-modal": "^3.8.1",
|
||||
"react-scripts": "2.1.5",
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import log from './utils/log';
|
||||
|
||||
const genericError = (
|
||||
<div id='content'>
|
||||
<Error messages={['There was an error and this content was unable to be displayed.']} />;
|
||||
<Error messages={['There was an error and this content was unable to be displayed.']} />
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import _ from 'lodash';
|
||||
import React from 'react';
|
||||
import Field from './field';
|
||||
|
||||
const ContainersPanel = ({spec}) => (
|
||||
<>
|
||||
{spec && spec.containers && spec.containers.map(item => (
|
||||
{spec && _.map(spec.containers, item => (
|
||||
<div key={item.name} className='contentPanel'>
|
||||
<Field name='Container'>{item.name}</Field>
|
||||
<Field name='Image'>{item.image}</Field>
|
||||
@@ -24,15 +25,15 @@ const ContainersPanel = ({spec}) => (
|
||||
|
||||
{item.resources && item.resources.requests && (
|
||||
<>
|
||||
<Field name='Cpu Request'>{item.resources.requests && item.resources.requests.cpu}</Field>
|
||||
<Field name='Memory Request'>{item.resources.requests && item.resources.requests.memory}</Field>
|
||||
<Field name='Cpu Request'>{item.resources.requests.cpu}</Field>
|
||||
<Field name='Memory Request'>{item.resources.requests.memory}</Field>
|
||||
</>
|
||||
)}
|
||||
|
||||
{item.resources && item.resources.limits && (
|
||||
<>
|
||||
<Field name='Cpu Limit'>{item.resources.limits && item.resources.limits.cpu}</Field>
|
||||
<Field name='Memory Limit'>{item.resources.limits && item.resources.limits.memory}</Field>
|
||||
<Field name='Cpu Limit'>{item.resources.limits.cpu}</Field>
|
||||
<Field name='Memory Limit'>{item.resources.limits.memory}</Field>
|
||||
</>
|
||||
)}
|
||||
|
||||
|
||||
@@ -41,8 +41,8 @@ export default class Menu extends Base {
|
||||
{/* Security */}
|
||||
<Group>
|
||||
<MenuItem title='Accounts' path='serviceaccount' resource='ServiceAccount' />
|
||||
<MenuItem title='Roles' path='role' resource='Role' additionalPaths={['clusterrolebinding']} />
|
||||
<MenuItem title='Bindings' path='rolebinding' resource='Role' additionalPaths={['clusterrole']} />
|
||||
<MenuItem title='Roles' path='role' resource='Role' additionalPaths={['clusterrole']} />
|
||||
<MenuItem title='Bindings' path='rolebinding' resource='Role' additionalPaths={['clusterrolebinding']} />
|
||||
<MenuItem title='Secrets' path='secret' resource='Secret' />
|
||||
</Group>
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ export default class PodsPanel extends Base {
|
||||
/>
|
||||
{!skipNodeName && <td>{x.spec.nodeName}</td>}
|
||||
<td>{x.status.phase}</td>
|
||||
<td>{x.spec.containers.length}</td>
|
||||
<td>{(x.spec.containers || []).length}</td>
|
||||
<td>{_.sumBy(x.status.containerStatuses, 'restartCount')}</td>
|
||||
<td><Cpu item={x} metrics={metrics} /></td>
|
||||
<td><Ram item={x} metrics={metrics} /></td>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
import {request, stream, streamResult, streamResults} from './apiProxy';
|
||||
import {request, stream, streamResult, streamResults, getToken} from './apiProxy';
|
||||
import log from '../utils/log';
|
||||
|
||||
const JSON_HEADERS = {Accept: 'application/json', 'Content-Type': 'application/json'};
|
||||
@@ -39,7 +39,14 @@ const apis = {
|
||||
};
|
||||
|
||||
function testAuth() {
|
||||
return request('/api/v1/namespaces', null, false);
|
||||
const token = getToken();
|
||||
const body = {
|
||||
apiVerstion: 'authentication.k8s.io/v1',
|
||||
kind: 'TokenReview',
|
||||
spec: {token},
|
||||
};
|
||||
|
||||
return post('/apis/authentication.k8s.io/v1/tokenreviews', body, false);
|
||||
}
|
||||
|
||||
async function apply(body) {
|
||||
@@ -151,16 +158,16 @@ function logs(namespace, name, container, cb) {
|
||||
}
|
||||
}
|
||||
|
||||
function post(url, json) {
|
||||
function post(url, json, autoLogoutOnAuthError = true) {
|
||||
const body = JSON.stringify(json);
|
||||
const opts = {method: 'POST', body, headers: JSON_HEADERS};
|
||||
return request(url, opts);
|
||||
return request(url, opts, autoLogoutOnAuthError);
|
||||
}
|
||||
|
||||
function put(url, json) {
|
||||
function put(url, json, autoLogoutOnAuthError = true) {
|
||||
const body = JSON.stringify(json);
|
||||
const opts = {method: 'PUT', body, headers: JSON_HEADERS};
|
||||
return request(url, opts);
|
||||
return request(url, opts, autoLogoutOnAuthError);
|
||||
}
|
||||
|
||||
function del(url) {
|
||||
|
||||
@@ -5,7 +5,7 @@ const nonHashedUrl = href.replace(hash, '').replace(search, '');
|
||||
const BASE_HTTP_URL = host === 'localhost:4653' ? 'http://localhost:4654' : nonHashedUrl;
|
||||
const BASE_WS_URL = BASE_HTTP_URL.replace('http', 'ws');
|
||||
|
||||
function getToken() {
|
||||
export function getToken() {
|
||||
return localStorage.authToken;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,8 +65,8 @@ export default class Ingress extends Base {
|
||||
<tr key={`${rule.host}:${path.path}`}>
|
||||
<td>{rule.host}</td>
|
||||
<td>{path.path}</td>
|
||||
<td>{path.backend.serviceName}</td>
|
||||
<td>{path.backend.servicePort}</td>
|
||||
<td>{path.backend && path.backend.serviceName}</td>
|
||||
<td>{path.backend && path.backend.servicePort}</td>
|
||||
</tr>
|
||||
))}
|
||||
</>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import _ from 'lodash';
|
||||
import React from 'react';
|
||||
import Base from '../components/base';
|
||||
import Filter from '../components/filter';
|
||||
@@ -45,8 +46,8 @@ export default class Ingresses extends Base {
|
||||
includeNamespace={true}
|
||||
href={`#/ingress/${x.metadata.namespace}/${x.metadata.name}`}
|
||||
/>
|
||||
<td>{x.spec.rules.map(y => y.host).join(' • ')}</td>
|
||||
<td>{x.spec.rules.flatMap(y => y.http.paths).map(y => y.path).join(' • ')}</td>
|
||||
<td>{_.map(x.spec.rules, y => y.host).join(' • ')}</td>
|
||||
<td>{_.flatMap(x.spec.rules, y => y.http.paths).map(y => y.path).join(' • ')}</td>
|
||||
</tr>
|
||||
)) : (
|
||||
<NoResults items={filtered} filter={filter} colSpan='6' />
|
||||
|
||||
@@ -75,7 +75,7 @@ export default class Nodes extends Base {
|
||||
{objectMap(x.metadata.labels)}
|
||||
</td>
|
||||
<td>
|
||||
{x.status.conditions.find(y => y.type === 'Ready').status}
|
||||
{x.status.conditions && (x.status.conditions.find(y => y.type === 'Ready') || {}).status}
|
||||
</td>
|
||||
<td>
|
||||
<CpuChart item={x} metrics={filteredMetrics} />
|
||||
|
||||
@@ -49,14 +49,16 @@ export default class PersistentVolume extends Base {
|
||||
</a>
|
||||
</Field>
|
||||
<Field name='Claim'>
|
||||
<a href={`#/persistentvolumeclaim/${item.spec.claimRef.namespace}/${item.spec.claimRef.name}`}>
|
||||
{`${item.spec.claimRef.namespace}/${item.spec.claimRef.name}`}
|
||||
</a>
|
||||
{item.spec.claimRef && (
|
||||
<a href={`#/persistentvolumeclaim/${item.spec.claimRef.namespace}/${item.spec.claimRef.name}`}>
|
||||
{`${item.spec.claimRef.namespace}/${item.spec.claimRef.name}`}
|
||||
</a>
|
||||
)}
|
||||
</Field>
|
||||
<Field name='Access Modes' value={item.spec.accessModes.join(' • ')} />
|
||||
<Field name='Capacity' value={item.spec.capacity.storage} />
|
||||
<Field name='Access Modes' value={item.spec.accessModes && item.spec.accessModes.join(' • ')} />
|
||||
<Field name='Capacity' value={item.spec.capacity && item.spec.capacity.storage} />
|
||||
<Field name='Reclaim Policy' value={item.spec.persistentVolumeReclaimPolicy} />
|
||||
<Field name='Local Path' value={item.spec.local.path} />
|
||||
<Field name='Local Path' value={item.spec.local && item.spec.local.path} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -54,7 +54,7 @@ export default class PersistentVolumeClaim extends Base {
|
||||
</a>
|
||||
</Field>
|
||||
<Field name='Modes' value={item.spec.accessModes.join(' • ')} />
|
||||
<Field name='Capacity' value={item.status.capacity.storage} />
|
||||
<Field name='Capacity' value={item.status.capacity && item.status.capacity.storage} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -52,7 +52,7 @@ export default class PersistentVolumeClaims extends Base {
|
||||
<td>{x.spec.storageClassName}</td>
|
||||
<td>{x.spec.accessModes.join(' • ')}</td>
|
||||
<td>{x.spec.volumeName}</td>
|
||||
<td>{x.status.capacity.storage}</td>
|
||||
<td>{x.status.capacity && x.status.capacity.storage}</td>
|
||||
</tr>
|
||||
)) : (
|
||||
<NoResults colSpan='9' items={filtered} filter={filter} />
|
||||
|
||||
@@ -44,7 +44,7 @@ export default class PersistentVolumes extends Base {
|
||||
href={`#/persistentvolume/${x.metadata.name}`}
|
||||
/>
|
||||
<td>{x.status.phase}</td>
|
||||
<td>{x.spec.capacity.storage}</td>
|
||||
<td>{x.spec.capacity && x.spec.capacity.storage}</td>
|
||||
</tr>
|
||||
)) : (
|
||||
<NoResults items={filtered} filter={filter} colSpan='5' />
|
||||
|
||||
+11
-5
@@ -36,9 +36,7 @@ export default class Pod extends Base {
|
||||
const {namespace, name} = this.props;
|
||||
const {item, metrics, events} = this.state || {};
|
||||
|
||||
const errors = item && item.status.conditions
|
||||
.filter(x => !!x.message)
|
||||
.map(x => x.message);
|
||||
const errors = getErrors(item);
|
||||
|
||||
const filteredEvents = filterByOwner(events, item);
|
||||
|
||||
@@ -62,7 +60,7 @@ export default class Pod extends Base {
|
||||
</>
|
||||
</ItemHeader>
|
||||
|
||||
{errors && <Error messages={errors} />}
|
||||
{errors && !!errors.length && <Error messages={errors} />}
|
||||
|
||||
<div className='charts'>
|
||||
<div className='charts_item'>
|
||||
@@ -99,7 +97,7 @@ export default class Pod extends Base {
|
||||
<Field name='Conditions'>
|
||||
{_.map(item.status.conditions, x => (
|
||||
<div key={x.type}>
|
||||
<span>{x.type}</span> • <span>{x.status}</span>
|
||||
<span>{x.type}</span> • <span>{x.status}</span> • <span>{x.message}</span>
|
||||
</div>
|
||||
))}
|
||||
</Field>
|
||||
@@ -164,3 +162,11 @@ function Ram({item, metrics}) {
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function getErrors(item) {
|
||||
if (!item) return [];
|
||||
if (item.status.message) return [item.status.message];
|
||||
if (item.status.conditions) return item.status.conditions.map(x => x.message).filter(x => !!x);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import _ from 'lodash';
|
||||
import React from 'react';
|
||||
import api from '../services/api';
|
||||
import EventsPanel from '../components/eventsPanel';
|
||||
@@ -65,7 +66,7 @@ export default class Service extends Base {
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{hasResults(ports) ? item.spec.ports.map(x => (
|
||||
{hasResults(ports) ? _.map(item.spec.ports, x => (
|
||||
<tr key={x.port}>
|
||||
<td>{x.name}</td>
|
||||
<td>{x.port}</td>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import _ from 'lodash';
|
||||
import React from 'react';
|
||||
import Base from '../components/base';
|
||||
import api from '../services/api';
|
||||
@@ -43,7 +44,7 @@ export default class ServiceAccount extends Base {
|
||||
<div>
|
||||
<MetadataFields item={item} />
|
||||
<Field name='Secrets'>
|
||||
{item.secrets.map(x => (
|
||||
{_.map(item.secrets, x => (
|
||||
<div key={x.name}>
|
||||
<a href={`#/secret/${namespace}/${x.name}`}>{x.name}</a>
|
||||
</div>
|
||||
|
||||
@@ -35,8 +35,7 @@ export default class Workloads extends Base {
|
||||
const {cronJobs, daemonSets, deployments, jobs, statefulSets, filter = '', sortBy, sortDirection} = this.state || {};
|
||||
const items = [cronJobs, daemonSets, deployments, jobs, statefulSets];
|
||||
|
||||
let filtered = filterControllers(filter, items);
|
||||
filtered = _.orderBy(filtered, [sortBy], [sortDirection]);
|
||||
const filtered = filterControllers(filter, items, sortBy, sortDirection);
|
||||
|
||||
const controllerCount = filtered && filtered.length;
|
||||
const pendingControllerCount = getPendingControllerCount(filtered);
|
||||
@@ -133,14 +132,14 @@ function getExpectedCount({spec, status}) {
|
||||
return spec.replicas || status.currentNumberScheduled || 0;
|
||||
}
|
||||
|
||||
function filterControllers(filter, items) {
|
||||
function filterControllers(filter, items, sortBy, sortDirection) {
|
||||
const results = items.flat();
|
||||
|
||||
if (results.length && items.some(x => !x)) return null;
|
||||
|
||||
return _(results)
|
||||
.flatten()
|
||||
.sortBy('metadata.name')
|
||||
.orderBy([sortBy], [sortDirection])
|
||||
.filter(x => test(filter, x.metadata.name))
|
||||
.value();
|
||||
}
|
||||
|
||||
+15
-7
@@ -47,15 +47,23 @@ function logging(req, res, next) {
|
||||
}
|
||||
|
||||
async function getOidc(req, res) {
|
||||
const authEndpoint = await getOidcEndpoint();
|
||||
res.json({authEndpoint});
|
||||
try {
|
||||
const authEndpoint = await getOidcEndpoint();
|
||||
res.json({authEndpoint});
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
}
|
||||
|
||||
async function postOidc(req, res) {
|
||||
const body = await toString(req);
|
||||
const {code, redirectUri} = JSON.parse(body);
|
||||
const token = await oidcAuthenticate(code, redirectUri);
|
||||
res.json({token});
|
||||
async function postOidc(req, res, next) {
|
||||
try {
|
||||
const body = await toString(req);
|
||||
const {code, redirectUri} = JSON.parse(body);
|
||||
const token = await oidcAuthenticate(code, redirectUri);
|
||||
res.json({token});
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
}
|
||||
|
||||
function onError(err, req, res) {
|
||||
|
||||
Reference in New Issue
Block a user