Skip to content

Commit

Permalink
Manageable modules
Browse files Browse the repository at this point in the history
  • Loading branch information
pbochynski committed Nov 22, 2023
1 parent 7ab135e commit 5f7f880
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 33 deletions.
83 changes: 52 additions & 31 deletions app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var modules = []
async function apply(res) {
let path = await resPath(res)
path += '?fieldManager=kubectl&fieldValidation=Strict&force=false'
let response = await fetch(API_PREFIX+path, { method: 'PATCH', headers: { 'content-type': 'application/apply-patch+yaml' }, body: JSON.stringify(res) })
let response = await fetch(API_PREFIX + path, { method: 'PATCH', headers: { 'content-type': 'application/apply-patch+yaml' }, body: JSON.stringify(res) })
return response
}
function channelDropdown() {
Expand Down Expand Up @@ -62,13 +62,13 @@ function channelDropdown() {
div.appendChild(ul)
div.appendChild(updateBtn)

if (API_PREFIX!='') {
if (API_PREFIX != '') {
let busolaBtn = document.createElement('button')
busolaBtn.setAttribute('class', 'btn btn-outline-primary btn-sm')
busolaBtn.setAttribute('type', 'button')
busolaBtn.textContent = 'Kyma Dashboard'
busolaBtn.addEventListener('click', openBusola)
div.appendChild(busolaBtn)
div.appendChild(busolaBtn)
}

return div
Expand All @@ -81,12 +81,12 @@ async function applyModule(m) {
await apply(m.cr.resource)
}
function openBusola() {
localStorage.setItem('busola.clusters','{"kyma":{"name":"kyma","kubeconfig":{"apiVersion":"v1","clusters":[{"cluster":{"server":"http://127.0.0.1:8001/backend"},"name":"kyma"}],"contexts":[{"context":{"cluster":"kyma","user":"admin"},"name":"kyma"}],"current-context":"kyma","kind":"Config","preferences":{},"users":[{"name":"admin","user":{"token":"tokentokentoken"}}]},"contextName":"kyma","config":{"storage":"localStorage"},"currentContext":{"cluster":{"cluster":{"server":"http://127.0.0.1:8001/backend"},"name":"kyma"},"user":{"name":"admin","user":{"token":"tokentokentoken"}}}}}')
window.open('/index.html','_blank')
localStorage.setItem('busola.clusters', '{"kyma":{"name":"kyma","kubeconfig":{"apiVersion":"v1","clusters":[{"cluster":{"server":"http://127.0.0.1:8001/backend"},"name":"kyma"}],"contexts":[{"context":{"cluster":"kyma","user":"admin"},"name":"kyma"}],"current-context":"kyma","kind":"Config","preferences":{},"users":[{"name":"admin","user":{"token":"tokentokentoken"}}]},"contextName":"kyma","config":{"storage":"localStorage"},"currentContext":{"cluster":{"cluster":{"server":"http://127.0.0.1:8001/backend"},"name":"kyma"},"user":{"name":"admin","user":{"token":"tokentokentoken"}}}}}')
window.open('/index.html', '_blank')
}

function get(path) {
return fetch(API_PREFIX+path).then((res) => {
return fetch(API_PREFIX + path).then((res) => {
if (res.status == 200) {
return res.json()
}
Expand All @@ -98,7 +98,7 @@ function deleteModuleResources(m) {
if (r.path == '/api/v1/namespaces/kyma-system') {
continue; // skip kyma-system deletion
}
fetch(API_PREFIX+r.path, { method: 'DELETE' })
fetch(API_PREFIX + r.path, { method: 'DELETE' })
}
}
async function removeModuleFromKymaCR(name) {
Expand All @@ -107,12 +107,21 @@ async function removeModuleFromKymaCR(name) {
for (let i = 0; i < kyma.spec.modules.length; ++i) {
if (kyma.spec.modules[i].name == name) {
let body = `[{"op":"remove","path":"/spec/modules/${i}"}]`
fetch(API_PREFIX+KYMA_PATH, { method: 'PATCH', headers: { 'content-type': 'application/json-patch+json' }, body })
fetch(API_PREFIX + KYMA_PATH, { method: 'PATCH', headers: { 'content-type': 'application/json-patch+json' }, body })
return
}
}
}
}
async function addModuleToKymaCR(name) {
let kyma = await get(KYMA_PATH)
if (kyma && kyma.spec.modules) {
let body = `[{"op":"add","path":"/spec/modules/-","value":{"name":"${name}"}}]`
fetch(API_PREFIX + KYMA_PATH, { method: 'PATCH', headers: { 'content-type': 'application/json-patch+json' }, body })
return
}
}

async function deleteModule(m) {
if (m.managed) {
modal("This is a managed module. Do you want to remove it from SKR managed resources?", "Delete confirmation", async () => {
Expand All @@ -128,7 +137,7 @@ async function deleteModule(m) {
modal(body, "Delete confirmation", async () => {
for (let i = 0; i < 5 && toDelete.length > 0; ++i) {
for (let i of toDelete) {
fetch(API_PREFIX+i, { method: 'DELETE' })
fetch(API_PREFIX + i, { method: 'DELETE' })
}
toDelete = await managedResourcesList(m)
setTimeout(() => checkStatus(), 1000)
Expand Down Expand Up @@ -235,13 +244,13 @@ async function exists(path) {
if (!path) {
return false;
}
let response = await fetch(API_PREFIX+path)
let response = await fetch(API_PREFIX + path)
return (response.status == 200)
}

async function cacheAPI(apiVersion) {
let url = (apiVersion === 'v1') ? '/api/v1' : `/apis/${apiVersion}`
let res = await fetch(API_PREFIX+url)
let res = await fetch(API_PREFIX + url)
if (res.status == 200) {
let body = await res.json()
groupVersions[apiVersion] = body
Expand All @@ -259,7 +268,7 @@ function deploymentList(m) {
if (r.status === true) {
badge = `<span class="badge bg-success">applied</span>`
html += `<li class="list-group-item"><small>
<a href="${API_PREFIX+r.path}" class="text-decoration-none" target="_blank">
<a href="${API_PREFIX + r.path}" class="text-decoration-none" target="_blank">
${r.resource.kind}: ${r.resource.metadata.name}</a> ${badge}</small></li>`
} else {
html += `<li class="list-group-item"><small>${r.resource.kind}: ${r.resource.metadata.name}</a> ${badge}</small></li>`
Expand Down Expand Up @@ -308,6 +317,16 @@ function applyBtn(m) {
})
return btn
}
function addBtn(m) {
let btn = document.createElement("button")
btn.textContent = "add"
btn.setAttribute('class', 'btn btn-outline-primary btn-sm')
btn.addEventListener("click", function (event) {
addModuleToKymaCR(m.name)
setTimeout(() => checkStatus(), 3000)
})
return btn
}

function detailsBtn(m) {
let btn = document.createElement("button")
Expand All @@ -329,24 +348,27 @@ function deleteBtn(m) {
})
return btn
}
function externalLink(href,name) {
function externalLink(href, name) {
if (href) {
return `<a href="${href}" class="text-decoration-none" target="_blank">
${name} <i class="bi bi-box-arrow-up-right"></i></a>`
${name} <i class="bi bi-box-arrow-up-right"></i></a>`
}
return ""
}
function configLink(m) {
if (m.cr.status) {
return `<a href="${API_PREFIX+m.cr.path}" class="text-decoration-none" target="_blank">
configuration </i></a>`
return `<a href="${API_PREFIX + m.cr.path}" class="text-decoration-none" target="_blank">
configuration </i></a>`
}
return "configuration"
}

function moduleCard(m) {
let buttons = document.createElement("div")
buttons.setAttribute('class', 'd-inline-flex gap-1')
if (m.manageable && !m.managed) {
buttons.appendChild(addBtn(m))
}
if (!m.managed && m.deploymentYaml) {
buttons.appendChild(applyBtn(m))
}
Expand All @@ -361,16 +383,16 @@ function moduleCard(m) {
let txt = document.createElement("div")
let version = "-"
if (m.deploymentVersion) {
version=m.deploymentVersion.split('/')[m.deploymentVersion.split('/').length - 1]
version = m.deploymentVersion.split('/')[m.deploymentVersion.split('/').length - 1]
}
let html = `<h5>${m.name} ${moduleBadge(m)}</h5>
<small>
module version: ${m.version} <br/>
deployment: ${resourcesBadge(m)} <br/>
${version} ${versionBadge(m)} ${availableBadge(m)} <br/>
${configLink(m)} ${crBadge(m)}<br/>
${externalLink(m.documentation,"docs")}
${externalLink(m.repository,"repo")}
${externalLink(m.documentation, "docs")}
${externalLink(m.repository, "repo")}
<br/>
</small>`
txt.innerHTML = html
Expand Down Expand Up @@ -417,17 +439,16 @@ function availableBadge(m) {
async function managedModules() {
let kyma = await get(KYMA_PATH)
if (kyma) {

for (let m of modules) {
if (m.name == 'istio') {
m.managed = true
continue;
}
if (kyma.spec.modules) {
let mm = kyma.spec.modules.find((mod) => mod.name == m.name)
m.managed = (mm) ? true : false
}
}
} else {
for (let m of modules) {
m.manageable = false
}
}
}

Expand Down Expand Up @@ -455,7 +476,7 @@ function checkStatus() {
for (let m of modules) {
resPath(m.cr.resource).then((p) => {
m.cr.path = p
return (p) ? fetch(API_PREFIX+p) : null
return (p) ? fetch(API_PREFIX + p) : null
}).then((res) => {
if (res) {
m.cr.status = (res.status == 200)
Expand All @@ -472,7 +493,7 @@ function checkStatus() {
m.available = false
m.actualVersion = undefined
if (r.path) {
fetch(API_PREFIX+r.path).then((res) => {
fetch(API_PREFIX + r.path).then((res) => {
if (res.status == 200) {
r.status = true
return res.json()
Expand All @@ -484,13 +505,13 @@ function checkStatus() {
}).then((json) => {
r.value = json
if (json && json.kind == 'Deployment') {
if (json.spec.template.spec.containers.length==1) {
if (json.spec.template.spec.containers.length == 1) {
m.actualVersion = json.spec.template.spec.containers[0].image
} else {
for (let c of json.spec.template.spec.containers){
if (!c.image.indexOf('proxy')>=0) {
for (let c of json.spec.template.spec.containers) {
if (!c.image.indexOf('proxy') >= 0) {
m.actualVersion = c.image
}
}
}
}
console.log(m.actualVersion, json.status)
Expand All @@ -511,7 +532,7 @@ function checkStatus() {
}

function getPods() {
fetch(API_PREFIX+'/api/v1/pods')
fetch(API_PREFIX + '/api/v1/pods')
.then((response) => response.json())
.then((podList) => {
pods = podList.items.sort((a, b) => {
Expand Down
2 changes: 1 addition & 1 deletion app/kyma.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<div class="container-fluid bg-dark">
<nav class="navbar navbar-dark bg-dark">
<svg width="92" height="25" xmlns="http://www.w3.org/2000/svg"><g fill="#FFFFFF" fill-rule="nonzero"><path d="M34.3833 20.325V4.5h3.45v6.5417L43.0667 4.5h4.0083l-5.3 6.1833 5.8333 9.6417H43.75l-4.2083-6.9917-1.6667 1.95V20.35z"/><path d="M47.3667 24.275l.7083-2.6083c.1583.0416.4333.1083.8333.1833a6.1667 6.1667 0 0 0 1.325.125c.313.0144.623-.0639.8917-.225a1.5333 1.5333 0 0 0 .5417-.7667l.2166-.5583-4.3333-11.5h3.5083l2.5 7.4 2.5-7.4H59.35l-4.725 12.6a8.425 8.425 0 0 1-.6417 1.3167 4.4 4.4 0 0 1-.8333 1c-.3241.28-.701.4925-1.1083.625a4.4 4.4 0 0 1-1.475.2166 11.5833 11.5833 0 0 1-2.0167-.1416c-.4917-.0917-.8833-.1834-1.1833-.2667zM61.2583 20.325v-11.4h3.4v1.7833a4.9167 4.9167 0 0 1 .6084-.6833 5.4583 5.4583 0 0 1 .8333-.65 4.4667 4.4667 0 0 1 1.025-.4833A3.65 3.65 0 0 1 68.3583 8.7a3.55 3.55 0 0 1 2.1334.5333 2.5 2.5 0 0 1 .95 1.475c.175-.2083.3833-.4333.6166-.675.2503-.2522.53-.4732.8334-.6583a4.7 4.7 0 0 1 1.0333-.4833A3.6667 3.6667 0 0 1 75.1667 8.7a3.9333 3.9333 0 0 1 1.4583.25 2.825 2.825 0 0 1 1.0333.725c.2784.3213.4832.6996.6 1.1083.1358.454.2004.9263.1917 1.4v8.1417h-3.4167v-7.2417c.0233-.406-.06-.811-.2416-1.175a1.0667 1.0667 0 0 0-.9834-.3916 2.1917 2.1917 0 0 0-1.1583.325 7.425 7.425 0 0 0-1.0917.8333v7.6667h-3.4v-7.2584c.0233-.406-.06-.811-.2416-1.175a1.075 1.075 0 0 0-.9834-.3916 2.225 2.225 0 0 0-1.175.325 7.5 7.5 0 0 0-1.1.8333v7.6667l-3.4-.0167zM80.825 17.4083a3.4583 3.4583 0 0 1 1.6667-3.0666 12.0083 12.0083 0 0 1 5.4166-1.4167v-.275a1.4 1.4 0 0 0-.3416-1 1.5333 1.5333 0 0 0-1.1667-.375 5.125 5.125 0 0 0-2 .3917 7.275 7.275 0 0 0-1.6667 1.025l-1.4416-1.975a8.5 8.5 0 0 1 .975-.7167 7.6167 7.6167 0 0 1 1.2166-.65 7.9333 7.9333 0 0 1 1.5334-.4583 10.2333 10.2333 0 0 1 1.9083-.1667 4.275 4.275 0 0 1 3.3333 1.1333 4.85 4.85 0 0 1 1.0167 3.3334v4.3833c-.007.5563.0152 1.1127.0667 1.6667.0338.3734.1179.7407.25 1.0916h-3.3834c-.0666-.25-.125-.5-.175-.775a4.2917 4.2917 0 0 1-.0833-.9A5.3833 5.3833 0 0 1 86.2333 20a4.8083 4.8083 0 0 1-2.2.475 3.6333 3.6333 0 0 1-1.2-.1917 3.1417 3.1417 0 0 1-1.025-.5916 2.6917 2.6917 0 0 1-.6916-.975 3.2417 3.2417 0 0 1-.2917-1.3084zm3.3333-.5916a1 1 0 0 0 .3417.8333c.2607.1892.5783.2833.9.2667a3.8333 3.8333 0 0 0 1.525-.275 3.2083 3.2083 0 0 0 1.0417-.7167v-2.1083a7.975 7.975 0 0 0-2.9167.7083 1.4833 1.4833 0 0 0-.9083 1.2917h.0166zM0 5v9.6a4.575 4.575 0 0 1 2.0833-.5h2.0834a11.95 11.95 0 0 0 7.6166-2.5c-.55-.5-1.0916-1-1.6166-1.5C7.5 7.6083 4.775 5.2417 0 5z"/><path d="M25.5083 5.1167c-4.675.225-7.175 2.5666-9.7666 5.0416C12.9 12.8583 9.9083 15.65 4.125 15.65H2.0833a2.0583 2.0583 0 0 0-1.8166 1.0917 2.1167 2.1167 0 0 0-.2667.975v2.6166h25.5l.0083-15.2166zM12.2583 4.1667C10.0833 2.075 7.9 0 3.55 0v4.1667a13.8 13.8 0 0 1 5 2.6916 13.275 13.275 0 0 0 3.7083-2.6916z"/><path d="M21.2833.7167c-3.6166.2083-5.525 2.0333-7.5 3.9583A18.0417 18.0417 0 0 1 9.775 7.8167c.4583.4166.9167.8333 1.3583 1.275.4417.4416 1.1584 1.0916 1.7584 1.6166.6166-.5333 1.2166-1.1 1.825-1.6666 1.8833-1.7917 3.825-3.6 6.6083-4.6334L21.2833.7167z"/></g></svg>
<a class="navbar-brand" href="#">modules 2023-11-21 11:26</a>
<a class="navbar-brand" href="#">modules 2023-11-22 09:33</a>
</nav>

</div>
Expand Down
9 changes: 9 additions & 0 deletions app/modules.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"/apis/security.istio.io/v1beta1/requestauthentications",
"/apis/telemetry.istio.io/v1alpha1/telemetries"
],
"manageable": true,
"versions": [
{
"version": "latest",
Expand Down Expand Up @@ -79,6 +80,7 @@
"/apis/serverless.kyma-project.io/v1alpha2/functions",
"/apis/operator.kyma-project.io/v1alpha1/serverlesses"
],
"manageable": true,
"versions": [
{
"version": "latest",
Expand Down Expand Up @@ -110,6 +112,7 @@
"/apis/services.cloud.sap.com/v1alpha1/serviceinstances",
"/apis/operator.kyma-project.io/v1alpha1/btpoperators"
],
"manageable": true,
"versions": [
{
"version": "latest",
Expand Down Expand Up @@ -140,6 +143,7 @@
"/apis/telemetry.kyma-project.io/v1alpha1/logpipelines",
"/apis/telemetry.kyma-project.io/v1alpha1/tracepipelines"
],
"manageable": true,
"versions": [
{
"version": "latest",
Expand Down Expand Up @@ -168,6 +172,7 @@
"managedResources": [
"/apis/operator.kyma-project.io/v1alpha1/nats"
],
"manageable": true,
"versions": [
{
"version": "latest",
Expand All @@ -188,6 +193,7 @@
"crYaml": "https://github.com/kyma-project/eventing-manager/releases/latest/download/eventing_default_cr.yaml",
"documentation": "https://kyma-project.io/#/eventing-manager/user/README",
"repository": "https://github.com/kyma-project/eventing-manager.git",
"manageable": true,
"managedResources": [
"/apis/eventing.kyma-project.io/v1alpha1/subscriptions",
"/apis/eventing.kyma-project.io/v1alpha2/subscriptions",
Expand All @@ -213,6 +219,7 @@
"crYaml": "https://github.com/kyma-project/application-connector-manager/releases/latest/download/default_application_connector_cr.yaml",
"documentation": "https://kyma-project.io/#/application-connector-manager/user/README",
"repository": "https://github.com/kyma-project/application-connector-manager.git",
"manageable": true,
"managedResources": [
"/apis/operator.kyma-project.io/v1alpha1/applicationconnectors"
],
Expand Down Expand Up @@ -243,6 +250,7 @@
"/apis/keda.sh/v1alpha1/scaledobjects",
"/apis/keda.sh/v1alpha1/triggerauthentications"
],
"manageable": true,
"versions": [
{
"version": "latest",
Expand All @@ -263,6 +271,7 @@
"managedResources": [
"apis/operator.kyma-project.io/v1alpha1/transparentproxies"
],
"manageable": true,
"cr": {
"resource": {
"apiVersion": "operator.kyma-project.io/v1alpha1",
Expand Down
4 changes: 3 additions & 1 deletion script/release-channels.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ async function loadModule(m) {

async function releaseChannels() {
for (let ch of channels) {
console.log("processing channel:", ch.name)
for (let mod of ch.modules) {
console.log(" -", mod.name)
for (let m of modules) {
if (m.name == mod.name) {
mod.deploymentYaml = m.deploymentYaml
Expand All @@ -46,6 +48,7 @@ async function releaseChannels() {
mod.resources = m.resources
mod.cr = m.cr
mod.community = m.community
mod.manageable = m.manageable
for (let v of m.versions) {
if (mod.version == v.version) {
if (v.managedResources) {
Expand Down Expand Up @@ -75,7 +78,6 @@ async function releaseChannels() {
}
await loadModule(mod)
}
console.log("channel loaded:", ch.name)
fs.writeFileSync(`${ch.name}.json`, JSON.stringify(ch.modules, null, 2))
console.log("channel written:", `${ch.name}.json`)
}
Expand Down

0 comments on commit 5f7f880

Please sign in to comment.