diff --git a/.gitignore b/.gitignore
index 1a579d47f2..7e5055d4ce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,7 @@
/standards/*/*.md
/standards/*/*.mdx
/standards/scs-*.yaml
+/user-docs/application-examples
# Dependencies
node_modules
diff --git a/docs.package.json b/docs.package.json
index 24a89f08cc..913c0f59d3 100644
--- a/docs.package.json
+++ b/docs.package.json
@@ -135,5 +135,11 @@
"source": ["documentation/overview.md"],
"target": "docs/turnkey-solution",
"label": ""
+ },
+ {
+ "repo": "SovereignCloudStack/opendesk-on-scs",
+ "source": "docs/*",
+ "target": "user-docs/application-examples",
+ "label": "opendesk-on-scs"
}
]
diff --git a/docusaurus.config.js b/docusaurus.config.js
index 16a143bfc8..a0b9f962b4 100644
--- a/docusaurus.config.js
+++ b/docusaurus.config.js
@@ -81,6 +81,16 @@ const config = {
// ... other options
}
],
+ [
+ '@docusaurus/plugin-content-docs',
+ {
+ id: 'user-docs',
+ path: 'user-docs',
+ routeBasePath: 'user-docs',
+ sidebarPath: require.resolve('./sidebarsUserDocs.js')
+ // ... other options
+ }
+ ],
[
'@docusaurus/plugin-content-docs',
{
@@ -120,6 +130,11 @@ const config = {
label: 'For Contributors',
position: 'left'
},
+ {
+ to: '/user-docs',
+ label: 'For Users',
+ position: 'left'
+ },
{ to: '/community', label: 'Community', position: 'left' },
{ to: '/docs/faq', label: 'FAQ', position: 'left' },
{
@@ -194,12 +209,19 @@ const config = {
// @ts-ignore
({
hashed: true,
- docsDir: ['docs', 'community', 'standards', 'contributor-docs'],
+ docsDir: [
+ 'docs',
+ 'community',
+ 'standards',
+ 'contributor-docs',
+ 'user-docs'
+ ],
docsRouteBasePath: [
'docs',
'community',
'standards',
- 'contributor-docs'
+ 'contributor-docs',
+ 'user-docs'
]
})
]
diff --git a/package-lock.json b/package-lock.json
index 1e341acd73..27d72e178f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,6 +27,7 @@
"lint-staged": "^13.1.2",
"markdownlint-cli2": "^0.7.1",
"markdownlint-rule-search-replace": "^1.0.9",
+ "node-fetch": "^2.7.0",
"prettier": "^2.8.4",
"prism-react-renderer": "^2.3.1",
"react": "^18.2.0",
@@ -6046,9 +6047,9 @@
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="
},
"node_modules/cookie": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
- "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
+ "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
"engines": {
"node": ">= 0.6"
}
@@ -8484,16 +8485,16 @@
}
},
"node_modules/express": {
- "version": "4.21.0",
- "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz",
- "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==",
+ "version": "4.21.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
+ "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
"body-parser": "1.20.3",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
- "cookie": "0.6.0",
+ "cookie": "0.7.1",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
@@ -14381,6 +14382,26 @@
"node": ">=18"
}
},
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
"node_modules/node-forge": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
@@ -18113,6 +18134,12 @@
"node": ">=6"
}
},
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "license": "MIT"
+ },
"node_modules/trim-lines": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
@@ -18868,6 +18895,12 @@
"resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz",
"integrity": "sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA=="
},
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "license": "BSD-2-Clause"
+ },
"node_modules/webpack": {
"version": "5.94.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz",
@@ -19170,6 +19203,16 @@
"node": ">=0.8.0"
}
},
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
diff --git a/package.json b/package.json
index 150e54d24b..c6d657d6e6 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,7 @@
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids",
"typecheck": "tsc",
- "postinstall": "node getDocs.js && node populateStds.js && node populateCerts.js",
+ "postinstall": "node getDocs.js && node populateStds.js && node populateCerts.js && node populateClouds.js",
"test": "echo \"Error: no test specified\" && exit 1",
"lint:md": "markdownlint-cli2 \"**/*.md\"",
"fix:md": "markdownlint-cli2-fix \"**/*.md\"",
@@ -54,6 +54,7 @@
"lint-staged": "^13.1.2",
"markdownlint-cli2": "^0.7.1",
"markdownlint-rule-search-replace": "^1.0.9",
+ "node-fetch": "^2.7.0",
"prettier": "^2.8.4",
"prism-react-renderer": "^2.3.1",
"react": "^18.2.0",
diff --git a/populateCerts.js b/populateCerts.js
index db5497057f..73b32627fa 100644
--- a/populateCerts.js
+++ b/populateCerts.js
@@ -1,108 +1,46 @@
+const fetch = require('node-fetch')
const fs = require('fs')
const YAML = require('yaml')
+async function fetchScopeTable(uuid, title, path) {
+ const response = await fetch(
+ `https://compliance.sovereignit.cloud/markdown/scope/${uuid}`
+ )
+ var text = await response.text()
+ text = `# ${title}\n\n${text}`
+ fs.writeFileSync(path, text, 'utf8')
+}
+
// how many outdated versions of any scope to include
const MAX_OLD = 1
const filenames = fs
- .readdirSync('standards/')
- .filter((fn) => fn.startsWith('scs-') && fn.endsWith('.yaml'))
+ .readdirSync('standards/')
+ .filter((fn) => fn.startsWith('scs-') && fn.endsWith('.yaml'))
const scopes = filenames.map((filename) => {
- return {
- ...YAML.parseDocument(fs.readFileSync(`standards/${filename}`, 'utf8')).toJSON(),
- filename,
- id: filename.substring(0, filename.length - 5),
- }
+ return {
+ ...YAML.parseDocument(
+ fs.readFileSync(`standards/${filename}`, 'utf8')
+ ).toJSON(),
+ filename,
+ id: filename.substring(0, filename.length - 5)
+ }
})
const today = new Date().toISOString().slice(0, 10)
const sidebarItems = scopes.map((scope) => {
- const matrix = {}
- const versionsShown = {}
- var numOld = 0
- var modules = {}
- scope.modules.forEach((module) => {
- modules[module.id] = module
- module.prettyName = module.id.startsWith('scs-') ? `${module.id}: ${module.name}` : module.name
- })
- scope.timeline.sort((a, b) => b.date.localeCompare(a.date))
- const current = scope.timeline.filter((entry) => entry.date <= today)
- const lookup = current.length ? current[0].versions : {}
- // sort in descending order, so we get the MAX_OLD most recent obsolete versions
- scope.versions.sort((a, b) => b.version.localeCompare(a.version));
- scope.versions.forEach((version) => {
- version.state = lookup[version.version] || 'deprecated'
- version.isStable = version.stabilized_at !== undefined && version.stabilized_at <= today
- version.isEffective = version.state == 'effective'
- if (['warn', 'effective', 'draft'].indexOf(version.state) == -1) {
- numOld += 1
- if (numOld > MAX_OLD) return
- }
- if (version.include === undefined) return
- versionsShown[version.version] = version
- version.include.forEach((include) => {
- if (include.ref === undefined) {
- include = {ref: include, parameters: {}}
- }
- const module = modules[include.ref]
- if (matrix[module.id] === undefined) {
- matrix[module.id] = {
- name: module.prettyName,
- columns: {},
- url: module.url,
- }
- }
- matrix[module.id].columns[version.version] = {
- parameters: include.parameters,
- }
- })
- })
-
- const rows = Object.values(matrix)
- const columns = Object.keys(versionsShown)
- rows.sort((a, b) => a.name.localeCompare(b.name));
- columns.sort((a, b) => a.localeCompare(b));
-
- lines = [`# ${scope.name}
-
-Note that the state _Stable_ is shown here if _stabilized at_ is in the future, whereas _Effective_ is shown here if _stabilized at_ is in the past and _deprecated at_ is unset or in the future.
-`]
- lines.push('| Scope versions -> | ' + columns.join(' | ') + ' |')
- lines.push('| :-- | ' + columns.map(() => ':--').join(' | ') + ' |')
- lines.push('| State | ' + columns.map((c) => versionsShown[c].state).join(' | ') + ' |')
- lines.push('| Stabilized at | ' + columns.map((c) => versionsShown[c].stabilized_at || '').join(' | ') + ' |')
- // lines.push('| Deprecated at | ' + columns.map((c) => versionsShown[c].deprecated_at || '').join(' | ') + ' |')
- // md doesn't allow intermediate header rows
- // lines.push('| :-- | ' + columns.map(() => ':--').join(' | ') + ' |')
- lines.push('| **Modules** | ' + columns.map((c) => ' '.repeat(c.length)).join(' | ') + ' |')
- // md doesn't allow intermediate header rows
- // lines.push('| :-- | ' + columns.map(() => ':--').join(' | ') + ' |')
- rows.forEach((row) => {
- lines.push(`| [${row.name}](${row.url}) | ` + columns.map((c) => row.columns[c]).map((col) => {
- if (col === undefined) {
- // this version of the cert does not include this standard
- return ''
- }
- let params = Object.entries(col.parameters || {}).map((entry) =>
- entry[1].startsWith('https://') ? `[${entry[0]}](${entry[1]})` : `${entry[0]}=${entry[1]}`
- ).join(', ')
- if (params.length) {
- params = ` (${params})`
- }
- return `X${params}`
- }).join(' | ') + ' |')
- })
- lines.push('') // file should end with a single newline character
- fs.writeFileSync(`standards/${scope.id}.md`, lines.join('\n'), 'utf8')
-
- const state = columns.filter((c) => versionsShown[c].isEffective).length ? '📜' : '✏️'
- return {
- type: 'doc',
- label: scope.name,
- id: scope.id,
+ fetchScopeTable(scope.uuid, scope.name, `standards/${scope.id}.md`).catch(
+ (e) => {
+ console.log(e)
}
+ )
+ return {
+ type: 'doc',
+ label: scope.name,
+ id: scope.id
+ }
})
var newSidebars = `module.exports = ${JSON.stringify(sidebarItems, null, ' ')}`
diff --git a/populateClouds.js b/populateClouds.js
new file mode 100644
index 0000000000..7fc1128332
--- /dev/null
+++ b/populateClouds.js
@@ -0,0 +1,18 @@
+const fetch = require('node-fetch')
+const fs = require('fs')
+
+async function insertCloudTable(pathIn, pathOut) {
+ const template = fs.readFileSync(pathIn, 'utf8')
+ const response = await fetch(
+ `https://compliance.sovereignit.cloud/markdown/table`
+ )
+ const text = template.replace('', await response.text())
+ fs.writeFileSync(pathOut, text, 'utf8')
+}
+
+insertCloudTable(
+ `standards/certification/overview.template.md`,
+ `standards/certification/overview.md`
+).catch((e) => {
+ console.log(e)
+})
diff --git a/sidebarsUserDocs.js b/sidebarsUserDocs.js
new file mode 100644
index 0000000000..2b6c44c679
--- /dev/null
+++ b/sidebarsUserDocs.js
@@ -0,0 +1,32 @@
+// @ts-check
+
+/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
+const sidebars = {
+ userDocs: [
+ 'index',
+ {
+ type: 'category',
+ label: 'Application Examples',
+ items: [
+ {
+ type: 'category',
+ label: 'OpenDesk on SCS',
+ link: {
+ type: 'generated-index'
+ },
+ items: [
+ 'application-examples/opendesk-on-scs/overview',
+ 'application-examples/opendesk-on-scs/quickstart',
+ 'application-examples/opendesk-on-scs/requirements',
+ 'application-examples/opendesk-on-scs/getting_started',
+ 'application-examples/opendesk-on-scs/configuration',
+ 'application-examples/opendesk-on-scs/user-import',
+ 'application-examples/opendesk-on-scs/contribute'
+ ]
+ }
+ ]
+ }
+ ]
+}
+
+module.exports = sidebars
diff --git a/standards/certification/overview.md b/standards/certification/overview.md
deleted file mode 100644
index 3511e38ea2..0000000000
--- a/standards/certification/overview.md
+++ /dev/null
@@ -1,16 +0,0 @@
-# Compliant clouds overview
-
-
-This is a list of clouds that we test on a nightly basis against the certificate scope _SCS-compatible IaaS_.
-
-| Name | Description | Operator | _SCS-compatible IaaS_ Compliance | HealthMon |
-| -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | ----------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------: |
-| [gx-scs](https://github.com/SovereignCloudStack/docs/blob/main/community/cloud-resources/plusserver-gx-scs.md) | Dev environment provided for SCS & GAIA-X context | plusserver GmbH | [![Compliance Status](https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-gx-scs-v4.yml?label=v4)](https://github.com/SovereignCloudStack/standards/actions/workflows/check-gx-scs-v4.yml) | [HM](https://health.gx-scs.sovereignit.cloud:3000/) |
-| [pluscloud open](https://www.plusserver.com/en/products/pluscloud-open)
- prod1
- prod2
- prod3
- prod4 | Public cloud for customers (4 regions) | plusserver GmbH |
- prod1 [![Compliance Status](https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-pco-prod1-v4.yml?label=v4)](https://github.com/SovereignCloudStack/standards/actions/workflows/check-pco-prod1-v4.yml)
- prod2 [![Compliance Status](https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-pco-prod2-v4.yml?label=v4)](https://github.com/SovereignCloudStack/standards/actions/workflows/check-pco-prod2-v4.yml)
- prod3 [![Compliance Status](https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-pco-prod3-v4.yml?label=v4)](https://github.com/SovereignCloudStack/standards/actions/workflows/check-pco-prod3-v4.yml)
- prod4 [![Compliance Status](https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-pco-prod4-v4.yml?label=v4)](https://github.com/SovereignCloudStack/standards/actions/workflows/check-pco-prod4-v4.yml) |
[HM1](https://health.prod1.plusserver.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?orgId=1&var-mycloud=plus-pco)
[HM2](https://health.prod1.plusserver.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?orgId=1&var-mycloud=plus-prod2)
[HM3](https://health.prod1.plusserver.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?orgId=1&var-mycloud=plus-prod3)
[HM4](https://health.prod1.plusserver.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?orgId=1&var-mycloud=plus-prod4) |
-| [Wavestack](https://www.noris.de/wavestack-cloud/) | Public cloud for customers | noris network AG/Wavecon GmbH | [![Compliance Status](https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-wavestack-v4.yml?label=v4)](https://github.com/SovereignCloudStack/standards/actions/workflows/check-wavestack-v4.yml) | [HM](https://health.wavestack1.sovereignit.cloud:3000/) |
-| [REGIO.cloud](https://regio.digital) | Public cloud for customers | OSISM GmbH | [![Compliance Status](https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-regio-a-v4.yml?label=v4)](https://github.com/SovereignCloudStack/standards/actions/workflows/check-regio-a-v4.yml) | broken |
-| [CNDS](https://cnds.io/) | Public cloud for customers | artcodix GmbH | [![Compliance Status](https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-artcodix-v4.yml?label=v4)](https://github.com/SovereignCloudStack/standards/actions/workflows/check-artcodix-v4.yml) | [HM](https://ohm.muc.cloud.cnds.io/) |
-| [aov.cloud](https://www.aov.de/) | Community cloud for customers | aov IT.Services GmbH | (soon) | [HM](https://health.aov.cloud/) |
-| PoC WG-Cloud OSBA | Cloud PoC for FITKO (yaook-based) | Cloud&Heat Technologies GmbH | [![Compliance Status](https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-poc-wgcloud-v4.yml?label=v4)](https://github.com/SovereignCloudStack/standards/actions/workflows/check-poc-wgcloud-v4.yml) | [HM](https://health.poc-wgcloud.osba.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?var-mycloud=poc-wgcloud&orgId=1) |
-| PoC KDO | Cloud PoC for FITKO | KDO Service GmbH / OSISM GmbH | [![Compliance Status](https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-poc-kdo-v4.yml?label=v4)](https://github.com/SovereignCloudStack/standards/actions/workflows/check-poc-kdo-v4.yml) | (soon) |
-| [syseleven](https://www.syseleven.de/en/products-services/openstack-cloud/)
- dus2
- ham1 | Public OpenStack Cloud (2 SCS regions) | SysEleven GmbH |
- dus2 [![Compliance Status](https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-syseleven-dus2-v4.yml?label=v4)](https://github.com/SovereignCloudStack/standards/actions/workflows/check-syseleven-dus2-v4.yml)
- ham1 [![Compliance Status](https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-syseleven-ham1-v4.yml?label=v4)](https://github.com/SovereignCloudStack/standards/actions/workflows/check-syseleven-ham1-v4.yml) |
(soon)
(soon) |
diff --git a/standards/certification/overview.template.md b/standards/certification/overview.template.md
new file mode 100644
index 0000000000..cb945d3ea2
--- /dev/null
+++ b/standards/certification/overview.template.md
@@ -0,0 +1,6 @@
+# Compliant clouds overview
+
+
+This is a list of clouds that we test on a nightly basis against the certificate scope _SCS-compatible IaaS_.
+
+
diff --git a/user-docs/index.md b/user-docs/index.md
new file mode 100644
index 0000000000..c7ad78afbf
--- /dev/null
+++ b/user-docs/index.md
@@ -0,0 +1,7 @@
+# Introduction
+
+## Welcome to the User Documentation of the Sovereign Cloud Stack (SCS)
+
+In this section, users will find helpful information and practical guides for working with SCS clouds. We provide insights into various application use cases, migration tutorials between different SCS cloud service providers, and showcase ways to communicate remotely with your cloud without a user interface.
+
+Discover best practices to make the most of your cloud, from introductions to specific applications to advanced use cases. Stay tuned for upcoming content designed to simplify your cloud experience.