├── .nvmrc ├── static ├── .nojekyll ├── img │ ├── favicon.ico │ ├── favicon.png │ ├── scs-og-basic.png │ ├── summit-social.png │ └── github-failed-dco.png └── data │ ├── featureContentData.json │ ├── additionalResourcesData.json │ └── architecturalOverviewData.json ├── standards ├── standards │ └── .gitkeep ├── image.png ├── certification │ ├── image.png │ ├── overview.template.md │ └── scopes-versions.md └── index.md ├── docs ├── 07-standards │ └── index.md ├── 02-iaas │ ├── overview │ │ ├── compute.md │ │ ├── network.md │ │ ├── storage.md │ │ ├── knowledge.md │ │ └── architecture.md │ ├── guides │ │ └── user-guide │ │ │ └── images │ │ │ └── user_data_backups_figure1.png │ └── deployment-examples │ │ └── artcodix │ │ └── index.mdx ├── 03-container │ ├── guides │ │ └── guide1.md │ ├── overview │ │ ├── knowledge.md │ │ └── architecture.md │ ├── deployment-examples │ │ └── a │ │ │ ├── index.md │ │ │ ├── hardware.md │ │ │ └── software.md │ └── index.md ├── 04-operating-scs │ ├── 02-monitoring │ │ └── index.md │ ├── 04-audits │ │ └── index.md │ ├── 06-logging │ │ └── index.md │ ├── 03-incident-management │ │ └── index.md │ ├── 05-lifecycle-management │ │ └── index.md │ └── overview.md ├── 01-getting-started │ ├── overview.md │ ├── virtualization.md │ └── containerization.md ├── turnkey-solution │ └── images │ │ └── combined_rack_visual.jpg ├── 05-iam │ ├── SCS-example-setup-configuration-description.md │ ├── iaas-roles.md │ ├── index.md │ └── intra-SCS-federation-setup-description-for-osism-doc-operations.md ├── 08-faq │ └── index.mdx └── index.mdx ├── user-docs ├── usage-hints │ ├── find-image │ │ ├── .flake8 │ │ ├── horizon.png │ │ ├── skyline.png │ │ ├── find_img2.py │ │ ├── find_img2.tf │ │ ├── find_img.tf │ │ ├── find_img.sh │ │ ├── find_img.py │ │ └── find_img.yaml │ ├── index.md │ └── diskless-flavor │ │ └── index.md └── index.md ├── .husky └── pre-commit ├── .lintstagedrc.json ├── babel.config.js ├── .prettierrc.json ├── .vscode └── extensions.json ├── community ├── tools │ ├── github │ │ ├── github-failed-dco.png │ │ ├── tips-and-tricks.md │ │ ├── branchprotection.md │ │ └── dco-and-licenses.md │ ├── nextcloud.md │ ├── matrix.md │ ├── mailinglists.md │ ├── zuul.md │ └── jitsi.md ├── collaboration │ ├── team-ops.md │ ├── team-iaas.md │ ├── team-container.md │ ├── sig-monitoring.md │ ├── sig-documentation.md │ ├── sig-community.md │ ├── sig-central-api.md │ ├── sig-standardization.md │ ├── team-iam.md │ └── index.mdx ├── cloud-resources │ ├── getting_started_openstack_anim.gif │ ├── clouds.yaml.sample │ ├── wavestack.md │ ├── plusserver-gx-scs.md │ ├── clouds-public.yaml │ ├── getting-started-openstack.md │ └── cloud-resources.md ├── governance │ ├── index.md │ └── project-board.md ├── index.md ├── contribute │ ├── doc-files-structure-guide.md │ ├── linting-guide.md │ ├── styleguide.md │ ├── docs-workflow-explanation.md │ ├── local-docusaurus-development-guide.mdx │ ├── adding-docs-guide.md │ └── styleguides │ │ └── ansible_styleguide.md └── central-services │ └── plusserver-gx-scs.md ├── .prettierignore ├── contributor-docs ├── development │ ├── index.md │ └── tests │ │ └── test-implementation-guide.md ├── index.md └── operations │ └── iam │ ├── identity-federation-in-scs.md │ └── openstack-federation-via-oidc.md ├── src ├── components │ ├── HomepageFeatures │ │ ├── styles.module.css │ │ └── index.tsx │ ├── architecturalmodel.module.css │ ├── button.module.css │ ├── Button.tsx │ ├── calendarModal.module.css │ ├── CalendarModal.tsx │ ├── contentcard.module.css │ ├── CommunityCalendar.tsx │ ├── ContentCard.tsx │ └── ArchitecturalModel.tsx ├── plugins │ ├── docusaurus-plugin-matomo-analytics │ │ ├── track.js │ │ └── index.js │ └── docusaurus-plugin-global-data │ │ └── index.js ├── pages │ ├── index.module.css │ └── index.tsx └── css │ └── custom.css ├── tsconfig.json ├── blog ├── 2022-10-28-first-blog-post.md └── authors.yml ├── sidebarsContributorDocs.js ├── .editorconfig ├── mlc_config.json ├── .github └── workflows │ ├── link-validator.yml │ ├── build.yml │ ├── build_and_deploy.yml │ ├── build_and_staging.yml │ └── pr-markdownlint.yml ├── .eslintrc.js ├── populateClouds.js ├── .gitignore ├── LICENSE-CODE ├── sidebarsStandards.js ├── sidebarsUserDocs.js ├── populateCerts.js ├── README.md ├── .markdownlint-cli2.jsonc ├── getDocs.js ├── sidebarsCommunity.js ├── package.json ├── docs.package.json └── docusaurus.config.js /.nvmrc: -------------------------------------------------------------------------------- 1 | v18 -------------------------------------------------------------------------------- /static/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /standards/standards/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/07-standards/index.md: -------------------------------------------------------------------------------- 1 | # Standards 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/02-iaas/overview/compute.md: -------------------------------------------------------------------------------- 1 | # Compute 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/02-iaas/overview/network.md: -------------------------------------------------------------------------------- 1 | # Network 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/02-iaas/overview/storage.md: -------------------------------------------------------------------------------- 1 | # Storage 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/03-container/guides/guide1.md: -------------------------------------------------------------------------------- 1 | # Guide 1 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/02-iaas/overview/knowledge.md: -------------------------------------------------------------------------------- 1 | # Knowledge 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/02-iaas/overview/architecture.md: -------------------------------------------------------------------------------- 1 | # Architecture 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/03-container/overview/knowledge.md: -------------------------------------------------------------------------------- 1 | # Knowledge 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/04-operating-scs/02-monitoring/index.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/04-operating-scs/04-audits/index.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/04-operating-scs/06-logging/index.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /user-docs/usage-hints/find-image/.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | ignore = E501 3 | -------------------------------------------------------------------------------- /docs/03-container/deployment-examples/a/index.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/03-container/overview/architecture.md: -------------------------------------------------------------------------------- 1 | # Architecture 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/04-operating-scs/03-incident-management/index.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/04-operating-scs/05-lifecycle-management/index.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx lint-staged -------------------------------------------------------------------------------- /docs/03-container/deployment-examples/a/hardware.md: -------------------------------------------------------------------------------- 1 | # Hardware Requirements 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/03-container/deployment-examples/a/software.md: -------------------------------------------------------------------------------- 1 | # Software Requirements 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/04-operating-scs/overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar: 1 3 | --- 4 | 5 | # Overview 6 | 7 | TODO 8 | -------------------------------------------------------------------------------- /standards/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SovereignCloudStack/docs/HEAD/standards/image.png -------------------------------------------------------------------------------- /docs/01-getting-started/overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar: 1 3 | --- 4 | 5 | # Overview 6 | 7 | TODO 8 | -------------------------------------------------------------------------------- /static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SovereignCloudStack/docs/HEAD/static/img/favicon.ico -------------------------------------------------------------------------------- /static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SovereignCloudStack/docs/HEAD/static/img/favicon.png -------------------------------------------------------------------------------- /docs/01-getting-started/virtualization.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar: 2 3 | --- 4 | 5 | # Virtualization 6 | 7 | TODO 8 | -------------------------------------------------------------------------------- /.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "*": "prettier --ignore-unknown --write", 3 | "*.md": "markdownlint-cli2-fix" 4 | } 5 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')] 3 | } 4 | -------------------------------------------------------------------------------- /docs/01-getting-started/containerization.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar: 3 3 | --- 4 | 5 | # Containerization 6 | 7 | TODO 8 | -------------------------------------------------------------------------------- /static/img/scs-og-basic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SovereignCloudStack/docs/HEAD/static/img/scs-og-basic.png -------------------------------------------------------------------------------- /static/img/summit-social.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SovereignCloudStack/docs/HEAD/static/img/summit-social.png -------------------------------------------------------------------------------- /standards/certification/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SovereignCloudStack/docs/HEAD/standards/certification/image.png -------------------------------------------------------------------------------- /static/img/github-failed-dco.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SovereignCloudStack/docs/HEAD/static/img/github-failed-dco.png -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSameLine": true, 3 | "singleQuote": true, 4 | "trailingComma": "none", 5 | "semi": false 6 | } 7 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "DavidAnson.vscode-markdownlint", 4 | "esbenp.prettier-vscode" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /community/tools/github/github-failed-dco.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SovereignCloudStack/docs/HEAD/community/tools/github/github-failed-dco.png -------------------------------------------------------------------------------- /user-docs/usage-hints/find-image/horizon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SovereignCloudStack/docs/HEAD/user-docs/usage-hints/find-image/horizon.png -------------------------------------------------------------------------------- /user-docs/usage-hints/find-image/skyline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SovereignCloudStack/docs/HEAD/user-docs/usage-hints/find-image/skyline.png -------------------------------------------------------------------------------- /community/collaboration/team-ops.md: -------------------------------------------------------------------------------- 1 | # Team Ops 2 | 3 | We build tooling and infrastructure design for easy, efficient and transparent ways to operate an SCS Cloud. 4 | -------------------------------------------------------------------------------- /docs/turnkey-solution/images/combined_rack_visual.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SovereignCloudStack/docs/HEAD/docs/turnkey-solution/images/combined_rack_visual.jpg -------------------------------------------------------------------------------- /community/collaboration/team-iaas.md: -------------------------------------------------------------------------------- 1 | # Team Iaas 2 | 3 | We build the reference implementation of the IaaS parts of SCS that informs and adheres to the SCS IaaS standards. 4 | -------------------------------------------------------------------------------- /community/cloud-resources/getting_started_openstack_anim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SovereignCloudStack/docs/HEAD/community/cloud-resources/getting_started_openstack_anim.gif -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # This .prettierignore file uses .gitignore syntax 2 | # see https://prettier.io/docs/en/ignore.html#ignoring-files-prettierignore 3 | 4 | .github 5 | .husky 6 | node_modules -------------------------------------------------------------------------------- /docs/02-iaas/guides/user-guide/images/user_data_backups_figure1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SovereignCloudStack/docs/HEAD/docs/02-iaas/guides/user-guide/images/user_data_backups_figure1.png -------------------------------------------------------------------------------- /contributor-docs/development/index.md: -------------------------------------------------------------------------------- 1 | # Developer documentation 2 | 3 | Welcome to the developer section of the contributor docs. Here you will find 4 | guidelines for the implementation of tooling such as the SCS conformance tests. 5 | -------------------------------------------------------------------------------- /user-docs/usage-hints/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Overview 3 | --- 4 | 5 | We collect and document best practices that allow developers 6 | to benefit from the SCS standardization and create automation 7 | that works across SCS clouds. 8 | -------------------------------------------------------------------------------- /src/components/HomepageFeatures/styles.module.css: -------------------------------------------------------------------------------- 1 | .features { 2 | display: flex; 3 | align-items: center; 4 | padding: 2rem 0; 5 | width: 100%; 6 | } 7 | 8 | .featureSvg { 9 | height: 200px; 10 | width: 200px; 11 | } 12 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // This file is not used in compilation. It is here just for a nice editor experience. 3 | "extends": "@tsconfig/docusaurus/tsconfig.json", 4 | "compilerOptions": { 5 | "jsx": "react", 6 | "baseUrl": "." 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /community/collaboration/team-container.md: -------------------------------------------------------------------------------- 1 | # Team Container 2 | 3 | The Team Container deals with all topics around Containers and Kubernetes. 4 | 5 | at the moment: Kubernetes Deployments via ClusterAPI 6 | in the future deployments via ClusterStacks 7 | KaaS Standard 8 | -------------------------------------------------------------------------------- /blog/2022-10-28-first-blog-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: first-blog-post 3 | title: First Blog Post 4 | authors: itrich 5 | tags: [community, howto] 6 | --- 7 | 8 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 9 | -------------------------------------------------------------------------------- /community/collaboration/sig-monitoring.md: -------------------------------------------------------------------------------- 1 | # SIG Monitoring 2 | 3 | The Special Interest Group (SIG) Monitoring meets on a fortnightly base (alternating with the audit log WG) to discuss the monitoring needs of SCS Operators, Users and Integrators. Together we shape how monitoring and observability within the SCS landscape looks like. 4 | -------------------------------------------------------------------------------- /sidebarsContributorDocs.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ 4 | const sidebars = { 5 | devDocs: [ 6 | { 7 | type: 'autogenerated', 8 | dirName: '.' // '.' means the current docs folder 9 | } 10 | ] 11 | } 12 | 13 | module.exports = sidebars 14 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /mlc_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignorePatterns": [ 3 | { 4 | "pattern": "^/" 5 | } 6 | ], 7 | "httpHeaders": [ 8 | { 9 | "urls": ["https://opensource.org/"], 10 | "headers": { 11 | "Accept-Encoding": "zstd, br, gzip, deflate" 12 | } 13 | } 14 | ], 15 | "aliveStatusCodes": [200, 300] 16 | } 17 | -------------------------------------------------------------------------------- /community/governance/index.md: -------------------------------------------------------------------------------- 1 | # Governance of the SCS Community 2 | 3 | The SCS Community is governed by the [SCS Project Board](/community/governance/project-board). The _Project Board_ is elected on a yearly basis. 4 | The governance of the community is described in the procedural standard [SCS-0005](https://docs.scs.community/standards/global/scs-0005). 5 | -------------------------------------------------------------------------------- /src/components/architecturalmodel.module.css: -------------------------------------------------------------------------------- 1 | .gradient { 2 | background: linear-gradient( 3 | 180deg, 4 | rgb(0, 97, 255, 0.2) 20%, 5 | rgba(80, 195, 165, 10) 50%, 6 | #50c3a5 80% 7 | ); 8 | border-radius: 16px; 9 | margin: 4px; 10 | display: block; 11 | } 12 | 13 | .border { 14 | border: rgba(0, 97, 255, 1) solid 4px; 15 | border-radius: 16px; 16 | margin: 4px; 17 | } 18 | 19 | .bottom { 20 | margin-bottom: 16px; 21 | } 22 | -------------------------------------------------------------------------------- /community/collaboration/sig-documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: SIG Documentation 3 | operator: Max Wolfs 4 | time: bi-weekly mondays 11-12 CET 5 | --- 6 | 7 | We curate and enhance the SCS Documentation, focusing on refining its information architecture for optimal usability. Our objective is to facilitate straightforward contributions from community developers and to provide operators with a clear, quick reference guide that accelerates the initiation of an SCS deployment. 8 | -------------------------------------------------------------------------------- /src/components/button.module.css: -------------------------------------------------------------------------------- 1 | .link { 2 | text-decoration: none; 3 | } 4 | 5 | .button { 6 | background-color: #50c3a5; /* Green */ 7 | border: none; 8 | color: white; 9 | padding: 15px 32px; 10 | text-align: center; 11 | text-decoration: none; 12 | display: inline-block; 13 | font-size: 16px; 14 | border-radius: 8px; 15 | font-weight: 600; 16 | cursor: pointer; 17 | } 18 | 19 | .button:hover { 20 | background-color: #0f5fe1; /* Green */ 21 | } -------------------------------------------------------------------------------- /src/plugins/docusaurus-plugin-matomo-analytics/track.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment' 3 | 4 | export default (function () { 5 | if (!ExecutionEnvironment.canUseDOM) { 6 | return null 7 | } 8 | return { 9 | onRouteUpdate({ location }) { 10 | _paq.push(['setCustomUrl', location.pathname]) 11 | _paq.push(['setDocumentTitle', document.title]) 12 | _paq.push(['trackPageView']) 13 | } 14 | } 15 | })() 16 | -------------------------------------------------------------------------------- /community/collaboration/sig-community.md: -------------------------------------------------------------------------------- 1 | # SIG Community 2 | 3 | In this meeting, we come together to shape our community strategy and coordinate collaborative efforts within our community. Our goal is to cultivate an open and welcoming community where we can share the message of SCS. We plan engaging community events, strive to make this open-source community even more inclusive, and aim to keep it informative, inspiring, and captivating. We warmly invite you to join us in our mission and become a part of this exciting journey! 4 | -------------------------------------------------------------------------------- /contributor-docs/index.md: -------------------------------------------------------------------------------- 1 | # Documentation for SCS Contributors 2 | 3 | Welcome to the Contributor Docs. This section is primarily for SCS Contributors and will contain documentation regarding the Development and Architecture of the Sovereign Cloud Stack and its components. You will find documents, explanations and guides regarding the tooling necessary for the development of SCS. 4 | 5 | If you want to contribute you can reach out to us via our [Matrix Channel](https://matrix.to/#/!TiDqlLmEUaXqTemaLc:matrix.org?via=matrix.org). 6 | -------------------------------------------------------------------------------- /.github/workflows/link-validator.yml: -------------------------------------------------------------------------------- 1 | on: [pull_request] 2 | name: Check links for modified files 3 | permissions: 4 | contents: read 5 | jobs: 6 | markdown-link-check: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v3 10 | - uses: gaurav-nelson/github-action-markdown-link-check@1.0.15 11 | with: 12 | use-quiet-mode: 'yes' 13 | use-verbose-mode: 'yes' 14 | check-modified-files-only: 'yes' 15 | config-file: 'mlc_config.json' 16 | base-branch: 'main' 17 | -------------------------------------------------------------------------------- /src/pages/index.module.css: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS files with the .module.css suffix will be treated as CSS modules 3 | * and scoped locally. 4 | */ 5 | 6 | .heroBanner { 7 | padding: 4rem 0; 8 | text-align: center; 9 | position: relative; 10 | overflow: hidden; 11 | } 12 | 13 | @media screen and (max-width: 996px) { 14 | .heroBanner { 15 | padding: 2rem; 16 | } 17 | } 18 | 19 | .buttons { 20 | display: flex; 21 | align-items: center; 22 | justify-content: center; 23 | } 24 | 25 | #marg { 26 | margin-top: 1rem; 27 | margin-bottom: 1rem; 28 | } 29 | -------------------------------------------------------------------------------- /src/components/Button.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styles from "./button.module.css"; 3 | 4 | interface ButtonProps { 5 | title: string; 6 | href?: string; 7 | handleClick: (e: any) => void; 8 | } 9 | 10 | const Button: React.FunctionComponent = (props) => { 11 | const { title, href, handleClick } = props; 12 | return ( 13 | 14 | 15 | 16 | ); 17 | }; 18 | 19 | export default Button; 20 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true 5 | }, 6 | extends: ['plugin:react/recommended', 'standard-with-typescript'], 7 | overrides: [ 8 | { 9 | files: 'docs/*.md', 10 | parser: 'eslint-plugin-markdownlint/parser', 11 | extends: 'plugin:markdownlint/recommended' 12 | } 13 | ], 14 | parserOptions: { 15 | ecmaVersion: 'latest', 16 | sourceType: 'module' 17 | }, 18 | plugins: ['react'], 19 | rules: [ 20 | { 21 | 'space-before-function-paren': 'never' 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /populateClouds.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch') 2 | const fs = require('fs') 3 | 4 | async function insertCloudTable(pathIn, pathOut) { 5 | const template = fs.readFileSync(pathIn, 'utf8') 6 | const response = await fetch( 7 | `https://compliance.sovereignit.cloud/markdown/table` 8 | ) 9 | const text = template.replace('', await response.text()) 10 | fs.writeFileSync(pathOut, text, 'utf8') 11 | } 12 | 13 | insertCloudTable( 14 | `standards/certification/overview.template.md`, 15 | `standards/certification/overview.md` 16 | ).catch((e) => { 17 | console.log(e) 18 | }) 19 | -------------------------------------------------------------------------------- /community/collaboration/sig-central-api.md: -------------------------------------------------------------------------------- 1 | # SIG Central API 2 | 3 | For defining a Common and Central interface for the Customers of SCS cloud to manage the Infrastructure cloud resources open stack and Kubernetes and identity and Access management. 4 | 5 | We want to define a single point of managment with consistent experience for managing the entire infrastructure. 6 | 7 | We aim to establish an unified and central interface that provides customers 8 | of the SCS clouds with the ability to manage cloud resources and/or services. 9 | 10 | SIG explores the possibilities for a central API by creating a MVP. 11 | -------------------------------------------------------------------------------- /user-docs/index.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | ## Welcome to the User Documentation of the Sovereign Cloud Stack (SCS) 4 | 5 | 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. 6 | 7 | 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. 8 | -------------------------------------------------------------------------------- /blog/authors.yml: -------------------------------------------------------------------------------- 1 | maxwolfs: 2 | name: Max Wolfs 3 | title: Knowledge Management Engineer @ SCS 4 | url: https://github.com/maxwolfs 5 | image_url: https://github.com/maxwolfs.png 6 | 7 | itrich: 8 | name: Eduard Itrich 9 | title: Community Manager @ SCS 10 | url: https://github.com/itrich 11 | image_url: https://github.com/itrich.png 12 | 13 | garloff: 14 | name: Kurt Garloff 15 | title: CEO @ SCS 16 | url: https://github.com/garloff 17 | image_url: https://github.com/garloff.png 18 | 19 | fkr: 20 | name: Felix Kronlage-Dammers 21 | title: Product Owner @ SCS 22 | url: https://github.com/fkr 23 | image_url: https://github.com/fkr.png -------------------------------------------------------------------------------- /community/cloud-resources/clouds.yaml.sample: -------------------------------------------------------------------------------- 1 | --- 2 | clouds: 3 | betacloud: 4 | profile: betacloud 5 | auth: 6 | username: USERNAME 7 | project_name: PROJECT 8 | project_domain_name: DOMAIN 9 | user_domain_name: DOMAIN 10 | pluscloudopen: 11 | profile: pluscloudopen 12 | auth: 13 | username: USERNAME 14 | project_name: PROJECT 15 | project_domain_name: DOMAIN 16 | user_domain_name: DOMAIN 17 | gx-scs: 18 | profile: gx-scs 19 | auth: 20 | username: u500924-USERNAME 21 | project_name: p500924-PROJECT 22 | project_domain_name: d500924 23 | user_domain_name: d500924 24 | -------------------------------------------------------------------------------- /community/tools/nextcloud.md: -------------------------------------------------------------------------------- 1 | # Nextcloud 2 | 3 | We have a [Nextcloud](https://nextcloud.com) 4 | [instance](https://scs.sovereignit.de) for sharing files, doing polls, ... 5 | setup for things that are not public. 6 | 7 | You can contribute to SCS via the github workflows, asking questions there (via 8 | opening issues against the issues repository), submitting pull requests, ... 9 | If you want to contribute on a regular basis, we are happy to also onboard you 10 | to the nextcloud and do an onboarding call. Nextcloud onboarding also adds you 11 | to the `scs-member@lists.scs.community` mailing list which also add you to the 12 | announcement list (described on the [Mailing Lists](mailinglists.md) page). 13 | -------------------------------------------------------------------------------- /community/cloud-resources/wavestack.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Getting Started with Wavestack 3 | version: 2023-03-02 4 | author: Linus Walther 5 | --- 6 | 7 | ## Getting Started with Wavestack 8 | 9 | ## URLs for access 10 | 11 | - UI (Horizon): [https://dashboard.wavestack.de/](https://dashboard.wavestack.de/) 12 | - API auth url (Keystone): [https://api.wavestack.de:5000](https://api.wavestack.de:5000) 13 | - Object Storage endpoint (S3/SWIFT): [https://rgw.muc5.wavestack.de:443](https://rgw.muc5.wavestack.de:443) 14 | 15 | ## Authentication (UI) 16 | 17 | For your login you will need: 18 | 19 | - Username 20 | - Password 21 | - Domain 22 | 23 | ## OpenStackClient (CLI) 24 | 25 | See: [Getting Started with OpenStack](./getting-started-openstack.md) 26 | -------------------------------------------------------------------------------- /community/collaboration/sig-standardization.md: -------------------------------------------------------------------------------- 1 | # SIG Standardization 2 | 3 | In this Special Interest Group, we discuss and align our activities and approach to standardization and certification. That is to say, we devise and refine the relevant concepts and processes; we work on a roadmap for new certificate versions; and we align on which standards are desireable for each certificate subject. We then work with the teams to align on existing or new standards. 4 | 5 | Besides aspects of openness and sovereignty, the main goal of our standards is interoperability. We should take the user perspective: As a member of a DevOps team developing a service (think SaaS or PaaS) for SCS, I need XYZ. Every standard should be abstract enough to work regardless of the SCS reference implementation. 6 | -------------------------------------------------------------------------------- /standards/certification/overview.template.md: -------------------------------------------------------------------------------- 1 | 2 | # Certification 3 | 4 | SCS certificates come with various scopes. See [Scopes and Versions](scopes-versions.md) for details. 5 | 6 | ## Becoming certified 7 | 8 | In order for a cloud service offering to obtain a certificate, it has to conform to all standards of the respective scope, which will be tested at regular intervals, and the results of these tests will be made available publicly. For more details on how to become certified, please consult the corresponding [document](/standards/scs-0004-v1-achieving-certification). 9 | 10 | ## Compliant cloud environments 11 | 12 | This is a list of clouds that we test on a nightly basis against the certificate scope _SCS-compatible IaaS_. 13 | 14 | 15 | -------------------------------------------------------------------------------- /user-docs/usage-hints/diskless-flavor/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: 'Preferring diskless flavors in SCS' 4 | author: 5 | - 'Kurt Garloff' 6 | --- 7 | 8 | ## Purpose 9 | 10 | Sovereign Cloud Stack (SCS) downgraded the formerly mandatory flavors with 11 | root disks to recommended ones when the flavor naming standard version 3 12 | became effective in the fall 2023. For many users using flavors that comprise 13 | a root disk is still the standard and at least when using CLI tooling, 14 | it's also simpler. 15 | 16 | This article documents how the diskless flavors can be used with common 17 | IaC tooling. 18 | 19 | ## Link to blog article 20 | 21 | We covered this in a blog article before, for which we 22 | [link here](https://scs.community/2023/08/21/diskless-flavors/) to our 23 | old web site for now. 24 | -------------------------------------------------------------------------------- /community/collaboration/team-iam.md: -------------------------------------------------------------------------------- 1 | # Team IAM 2 | 3 | The Team IAM deals with topics around Identity and Access Management. 4 | 5 | Users that access cloud and container infrastructure need to authenticate themselves and then authorizations to see and access resources from the infrastructure are derived from the identity of the users as they belong to groups and are roles are assigned to them (or the groups they belong to). 6 | 7 | Sovereign Cloud Stack has the goal that user identities can used across several layers in the stack (most importantly IaaS and Container layer), that user management should be a self-service capability and that user identities can be federated, i.e. user identities and authentication from one SCS cloud (or from one standards-compliant Identity Provider) can be used in other SCS clouds. Federation is an imporant principle in SCS. 8 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: 3 | workflow_dispatch: 4 | pull_request: 5 | 6 | permissions: 7 | contents: read 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout Repository 13 | uses: actions/checkout@v3 14 | with: 15 | ref: ${{ github.head_ref }} 16 | - name: Setup Node 17 | uses: actions/setup-node@v3 18 | with: 19 | node-version: 20 20 | - name: Cache dependencies 21 | uses: actions/cache@v3 22 | with: 23 | path: ~/.npm 24 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} 25 | restore-keys: | 26 | ${{ runner.os }}-node- 27 | 28 | - name: Install dependencies and build page 29 | run: | 30 | npm ci 31 | npm run build 32 | -------------------------------------------------------------------------------- /community/tools/matrix.md: -------------------------------------------------------------------------------- 1 | # Matrix 2 | 3 | We have created an [open community space on the Matrix federation](https://matrix.to/#/!TiDqlLmEUaXqTemaLc:matrix.org?via=matrix.org). Feel free to join the several channels and start chatting with our community. A good starting point is entering the [General & Announcements](https://matrix.to/#/#scs-general:matrix.org) and the [Tech](https://matrix.to/#/#scs-tech:matrix.org) channel. 4 | 5 | ## Client and Registration 6 | 7 | To connect to the Matrix federation, you will need an account on a federated homeserver and a client. The easiest way to join us is register on the popular `matrix.org` homeserver via the Element web client: [https://app.element.io/#/register](https://app.element.io/#/register]). A list of curated Matrix clients is collected on the official Matrix website: [https://matrix.org/clients/](https://matrix.org/clients/) 8 | -------------------------------------------------------------------------------- /src/components/calendarModal.module.css: -------------------------------------------------------------------------------- 1 | .modal { 2 | position: fixed; 3 | left: 0; 4 | right: 0; 5 | top: 0; 6 | bottom: 0; 7 | background-color: rgba(0, 0, 0, 0.5); 8 | display: flex; 9 | align-items: center; 10 | justify-content: center; 11 | z-index: 1000; 12 | position: fixed; 13 | overflow-y: scroll; 14 | } 15 | 16 | @media only screen and (max-width: 600px) { 17 | .modalContent { 18 | height: 100%; 19 | } 20 | } 21 | 22 | .modalContent { 23 | max-height: 100%; 24 | max-width: 100%; 25 | width: 500px; 26 | background-color: #fff; 27 | } 28 | 29 | .modalTitle { 30 | padding: 32px; 31 | border-bottom: #eee 2px solid; 32 | } 33 | 34 | .modalDescription { 35 | padding: 32px; 36 | } 37 | 38 | .modalH2 { 39 | margin: 0; 40 | } 41 | 42 | .buttonBox { 43 | text-align: left; 44 | } 45 | -------------------------------------------------------------------------------- /static/data/featureContentData.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "title": "Introduction to SCS", 4 | "body": "Get to know SCS better and learn about the background.", 5 | "url": "/docs", 6 | "buttonText": "Get Started" 7 | }, 8 | { 9 | "title": "Releases", 10 | "body": "The latest release of the SCS reference implementation is R8. Check out the Release Notes.", 11 | "url": "/docs/releases/Release8", 12 | "buttonText": "Learn More" 13 | }, 14 | { 15 | "title": "Frequently Asked Questions", 16 | "body": "You are curious what SCS is all about, what it can do and what it can't?", 17 | "url": "/docs/faq", 18 | "buttonText": "Get Answers" 19 | }, 20 | { 21 | "title": "Existing Public Clouds", 22 | "body": "There are SCS compliant public clouds in production.", 23 | "url": "/standards/certification/overview#compliant-cloud-environments", 24 | "buttonText": "Test Them" 25 | } 26 | ] 27 | -------------------------------------------------------------------------------- /community/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | title: Overview 4 | --- 5 | 6 | ## Welcome to our SCS Community 7 | 8 | Sovereign Cloud Stack is an open community of providers and end-users joining forces in defining, implementing and operating a fully open, federated, compatible platform. We actively encourage you to contribute either code, documentation or issues and to participate in the various discussions happening on GitHub or during our various meetings. 9 | 10 | We have created an open community space on the [Matrix network](https://matrix.to/#/#scs-community:matrix.org). Feel free to join the several channels and start interacting with the community. A good starting point is entering the [General & Announcements](https://matrix.to/#/#scs-general:matrix.org) and the [Tech channel](https://matrix.to/#/#scs-tech:matrix.org). 11 | 12 | Check out our [Community Calendar](/community/collaboration) to know when our several Teams and SIGs meet. 13 | -------------------------------------------------------------------------------- /standards/certification/scopes-versions.md: -------------------------------------------------------------------------------- 1 | # Scopes and versions 2 | 3 | SCS provides a certification framework consisting of six different kinds of certificates of varying scope. 4 | These scopes can be sorted into two dimensions: 5 | 6 | 1. _certification level_, of which there are three: 7 | - SCS-compatible 8 | - SCS-open 9 | - SCS-sovereign 10 | 2. _cloud layer_, of which there are two: 11 | - infastructure as a service (IaaS) 12 | - Kubernetes as a service (KaaS) 13 | 14 | So, for instance, a certificate can have the scope _SCS-compatible IaaS_ or _SCS-sovereign KaaS_. 15 | 16 | Each scope corresponds to a set of standards. As these standards progress, so do the scopes, and we keep track of this by versioning. Each version undergoes a lifecycle of Draft, Stable, and Deprecated, and we aim to keep at most one version stable at the same time, with the exception of a transition period of 4 to 6 weeks. 17 | 18 | ![Alt text](image.png) 19 | -------------------------------------------------------------------------------- /community/tools/github/tips-and-tricks.md: -------------------------------------------------------------------------------- 1 | # Tips and Tricks 2 | 3 | ## Octo Reminder - your friendly assistant 4 | 5 | Are you tired of keeping track of planned changes or issues you scheduled for the future? Our [Octo Reminder](https://github.com/apps/octo-reminder) is here to safe you from unneeded cognitive load! 6 | 7 | The app configuration is stored in our [`.github`](https://github.com/SovereignCloudStack/.github/) repository. Using the bot is fairly simple: 8 | 9 | - To schedule a reminder, simply comment with `/remind-me [date] [message]` on an issue or pull request. The bot will answer and mention you in the particular issue/pull request upon reaching the configured date. 10 | - If you don't specify a time for the reminder, the bot will use 9:00 CET as default reminder time. 11 | - The date and time can be anything that [momentjs](https://momentjs.com/docs/#/parsing/) understands, e.g. an ISO 8601 string or a relative string such as `tomorrow` or `next week`. 12 | -------------------------------------------------------------------------------- /standards/index.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | The Sovereign Cloud Stack (SCS) is a community-driven project that curates a set of standards—including both existing standards, such as the OpenInfra interoperability guides or the CNCF Kubernetes conformance, and newly created ones—to enable and ensure compatibility, openness, and sovereignty of cloud services across a wide range of providers, particularly small and medium businesses. 4 | 5 | In addition, SCS provides a certification framework that enables these providers to verify and advertise their compliance with these standards. This framework consists of six kinds of certificates of varying scope, where each scope corresponds to a subset of the set of standards mentioned above. 6 | 7 | ![Alt text](image.png) 8 | 9 | Learn more about these scopes as well as the currently certified clouds under [Certification](certification/overview.md). More details on individual standards can be found under [Standards](standards/overview.mdx). 10 | -------------------------------------------------------------------------------- /user-docs/usage-hints/find-image/find_img2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # find_img2.py 4 | # 5 | # Find images for opentofu/terraform 6 | # 7 | # (c) Kurt Garloff , 11/2025 8 | # SPDX-License-Identifier: MIT 9 | "This module finds the a distribution image with a given purpose" 10 | 11 | import sys 12 | import json 13 | import find_img 14 | 15 | try: 16 | in_data = json.loads(sys.stdin.read()) 17 | conn = find_img.openstack.connect() # cloud=os.environ["OS_CLOUD"]) 18 | images = find_img.find_image(conn, in_data["os_distro"], in_data["os_version"], in_data["os_purpose"]) 19 | for img in images: 20 | print(f"DEBUG: {img[0]} {img[1]}", file=sys.stderr) 21 | if not (len(images)): 22 | print(f"No image found for {in_data}", file=sys.stderr) 23 | sys.exit(1) 24 | output = { "image_id": images[0][0], 25 | "image_name": images[0][1] } 26 | print(json.dumps(output)) 27 | 28 | except Exception as e: 29 | print(f"Error: {str(e)}", file=sys.stderr) 30 | sys.exit(2) 31 | -------------------------------------------------------------------------------- /community/cloud-resources/plusserver-gx-scs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Getting Started Gaia-X Demonstrator @ plusserver 3 | version: 2022-12-22 4 | author: Ralf Heiringhoff, Mathias Fechner 5 | --- 6 | 7 | ## Getting Started on SCS2 8 | 9 | The environment SCS2 is maintained by 10 | PlusServer as reference environment and PS has agreed to provide community 11 | resources on SCS2. All SCS community activities that continue to be needed 12 | should move to SCS2. 13 | 14 | ### URLs for accessing SCS2 15 | 16 | - UI (horizon): [https://scs2.api.pco.get-cloud.io/](https://scs2.api.pco.get-cloud.io/) 17 | - API auth URL: [https://scs2.api.pco.get-cloud.io:5000/](https://scs2.api.pco.get-cloud.io:5000/) 18 | - Object Storage EP: [https://scs2.api.pco.get-cloud.io:8080/](https://scs2.api.pco.get-cloud.io:8080/) 19 | 20 | ### Authentication (UI) 21 | 22 | For your login you will need: 23 | 24 | - Username (`u500924-<$github-handle>`) 25 | - Password 26 | - Domain (`d500924`) 27 | 28 | ### Getting Started with OpenStack 29 | 30 | See [Getting Started with OpenStack](./getting-started-openstack.md) 31 | -------------------------------------------------------------------------------- /community/cloud-resources/clouds-public.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | public-clouds: 3 | betacloud: 4 | auth: 5 | auth_url: https://api-1.betacloud.de:5000 6 | interface: 'public' 7 | regions: 8 | - name: betacloud-1 9 | identity_api_version: 3 10 | image_format: raw 11 | block_storage_api_version: 3 12 | pluscloudopen: 13 | auth: 14 | auth_url: https://prod1.api.pco.get-cloud.io:5000 15 | interface: 'public' 16 | regions: 17 | - name: prod1 18 | identity_api_version: 3 19 | image_format: raw 20 | block_storage_api_version: 3 21 | gx-scs: 22 | auth: 23 | auth_url: https://api.gx-scs.sovereignit.cloud:5000 24 | interface: 'public' 25 | regions: 26 | - name: RegionOne 27 | identity_api_version: 3 28 | image_format: raw 29 | block_storage_api_version: 3 30 | wavestack: 31 | auth: 32 | auth_url: https://api.wavestack.de:5000 33 | interface: 'public' 34 | regions: 35 | - name: MUC5 36 | identity_api_version: 3 37 | image_format: raw 38 | block_storage_api_version: 3 39 | -------------------------------------------------------------------------------- /src/plugins/docusaurus-plugin-global-data/index.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const fs = require('fs').promises // Use fs.promises for async/await 3 | 4 | function globalDataPlugin(context, options) { 5 | return { 6 | name: 'global-data-plugin', 7 | 8 | async loadContent() { 9 | const data = {} 10 | 11 | const datasetPaths = { 12 | architecturalOverviewData: 'static/data/architecturalOverviewData.json', 13 | additionalResourcesData: 'static/data/additionalResourcesData.json', 14 | featureContentData: 'static/data/featureContentData.json' 15 | // Add more datasets here 16 | } 17 | 18 | for (const [key, filePath] of Object.entries(datasetPaths)) { 19 | const jsonFilePath = path.join(context.siteDir, filePath) 20 | data[key] = JSON.parse(await fs.readFile(jsonFilePath, 'utf8')) 21 | } 22 | 23 | return data 24 | }, 25 | 26 | async contentLoaded({ content, actions }) { 27 | const { setGlobalData } = actions 28 | setGlobalData(content) 29 | } 30 | } 31 | } 32 | 33 | module.exports = globalDataPlugin 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Content Dependencies from docs.package.json 2 | /repo_to_be_edited_ 3 | /docs/02-iaas/components 4 | /docs/02-iaas/guides 5 | /docs/02-iaas/guides/configuration-guides 6 | /docs/02-iaas/guides/deploy-guide 7 | /docs/02-iaas/guides/operations-guide 8 | /docs/02-iaas/guides/troubleshooting-guides 9 | /docs/02-iaas/guides/upgrade-guides 10 | /docs/02-iaas/guides/index.md 11 | /docs/02-iaas/deployment-examples/cloud-in-a-box 12 | /docs/02-iaas/deployment-examples/testbed 13 | /docs/03-container/components 14 | /docs/04-operating-scs/components 15 | /docs/04-operating-scs/01-guides 16 | /docs/06-releases 17 | /docs/turnkey-solution 18 | /standards/*.md 19 | /standards/*/*.md 20 | /standards/*/*.mdx 21 | /standards/scs-*.yaml 22 | /user-docs/application-examples 23 | 24 | # Dependencies 25 | node_modules 26 | 27 | # Production 28 | /build 29 | 30 | # Generated files 31 | .docusaurus 32 | .cache-loader 33 | sidebarsStandardsItems.js 34 | sidebarsCertificationItems.js 35 | 36 | # Misc 37 | .DS_Store 38 | .env.local 39 | .env.development.local 40 | .env.test.local 41 | .env.production.local 42 | 43 | npm-debug.log* 44 | yarn-debug.log* 45 | yarn-error.log* 46 | -------------------------------------------------------------------------------- /LICENSE-CODE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Facebook, Inc. and its affiliates. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /src/components/HomepageFeatures/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import clsx from 'clsx'; 3 | import styles from './styles.module.css'; 4 | 5 | type FeatureItem = { 6 | title: string; 7 | Svg: React.ComponentType>; 8 | description: JSX.Element; 9 | }; 10 | 11 | const FeatureList: FeatureItem[] = [ 12 | 13 | ]; 14 | 15 | function Feature({title, Svg, description}: FeatureItem) { 16 | return ( 17 |
18 |
19 | 20 |
21 |
22 |

{title}

23 |

{description}

24 |
25 |
26 | ); 27 | } 28 | 29 | export default function HomepageFeatures(): JSX.Element { 30 | return ( 31 |
32 |
33 |
34 | {FeatureList.map((props, idx) => ( 35 | 36 | ))} 37 |
38 |
39 |
40 | ); 41 | } 42 | -------------------------------------------------------------------------------- /community/contribute/doc-files-structure-guide.md: -------------------------------------------------------------------------------- 1 | # Documentation Files Structure 2 | 3 | ## Structure Best Practice 4 | 5 | ### Overview - mandatory 6 | 7 | - What is it and for what do I need this? What benefits does it have for users? 8 | - What organization/company does this belong to? (Link to company/organization) 9 | - Where am I – as module – within the bigger context of SCS? 10 | 11 | ### Requirements - mandatory 12 | 13 | - What minimal requirements do i need to quickstart? 14 | 15 | ### Quickstart - optional. If it is possible, then mandatory 16 | 17 | - Link to requirements 18 | - What is the aim of this quickstart guide? 19 | - Caution: only for testing, not for production 20 | - Rule: one line per command for easy copy&paste and one line for description where possible 21 | - Rule: only one working path for installation! 22 | 23 | ### Getting Started - mandatory 24 | 25 | - Aim is a production ready installation 26 | 27 | ### Configuration – mandatory 28 | 29 | - Showing all possible config options 30 | 31 | ### Contribute – mandatory 32 | 33 | - Description for how can i contribute with Link to Github repository 34 | 35 | ### FAQ`s – optional 36 | 37 | - Roadmap - optional 38 | -------------------------------------------------------------------------------- /src/css/custom.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Any CSS included here will be global. The classic template 3 | * bundles Infima by default. Infima is a CSS framework designed to 4 | * work well for content-centric websites. 5 | */ 6 | 7 | table { 8 | display: table!important; 9 | } 10 | 11 | /* You can override the default Infima variables here. */ 12 | :root { 13 | --ifm-color-primary: #0F5FE1; 14 | --ifm-color-primary-dark: ##0e56cb; 15 | --ifm-color-primary-darker: ##0c4cb4; 16 | --ifm-color-primary-darkest: ##0b439e; 17 | --ifm-color-primary-light: ##276fe4; 18 | --ifm-color-primary-lighter: ##3f7fe7; 19 | --ifm-color-primary-lightest: ##578fea; 20 | --ifm-code-font-size: 95%; 21 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); 22 | } 23 | 24 | /* For readability concerns, you should choose a lighter palette in dark mode. */ 25 | [data-theme='dark'] { 26 | --ifm-color-primary: #0F5FE1; 27 | --ifm-color-primary-dark: ##0e56cb; 28 | --ifm-color-primary-darker: ##0c4cb4; 29 | --ifm-color-primary-darkest: ##0b439e; 30 | --ifm-color-primary-light: ##276fe4; 31 | --ifm-color-primary-lighter: ##3f7fe7; 32 | --ifm-color-primary-lightest: ##578fea; 33 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); 34 | } 35 | -------------------------------------------------------------------------------- /static/data/additionalResourcesData.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "title": "Get in touch", 4 | "body": "Come into our Matrix Chat in the SCS | Tech Room.", 5 | "url": "https://matrix.to/#/#scs-tech:matrix.org", 6 | "buttonText": "Join Now" 7 | }, 8 | { 9 | "title": "Come to our Meet-Ups", 10 | "body": "Our working groups and special interest groups meet weekly or biweekly. When? Find out within our public community calendar.", 11 | "url": "/community/collaboration", 12 | "buttonText": "Learn More" 13 | }, 14 | { 15 | "title": "Standardization in progress", 16 | "body": "Get to know our current Decision Records and Standards.", 17 | "url": "/standards", 18 | "buttonText": "Start Now" 19 | }, 20 | { 21 | "title": "Deployment Examples", 22 | "body": "Get to know different ways to deploy SCS with cloud resources or on bare metal.", 23 | "url": "/docs/category/deployment-examples", 24 | "buttonText": "Explore Cases" 25 | }, 26 | { 27 | "title": "Application Examples", 28 | "body": "Discover best practices to make the most of your cloud, from introductions to specific applications to advanced use cases.", 29 | "url": "/user-docs/category/application-examples", 30 | "buttonText": "Explore Cases" 31 | } 32 | ] 33 | -------------------------------------------------------------------------------- /sidebarsStandards.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ 2 | const sidebars = { 3 | standards: [ 4 | 'index', 5 | { 6 | type: 'category', 7 | label: 'Certification', 8 | link: { 9 | type: 'doc', 10 | id: 'certification/overview' 11 | }, 12 | items: [ 13 | { 14 | type: 'category', 15 | label: 'Scopes and Versions', 16 | link: { 17 | type: 'doc', 18 | id: 'certification/scopes-versions' 19 | }, 20 | items: require('./sidebarsCertificationItems.js') // this file will be generated entirely by `populateCerts.js` via npm post-install hook found in the package.json 21 | }, 22 | { 23 | type: 'doc', 24 | label: 'Compliance Check Pipeline', 25 | id: 'certification/pipeline' 26 | } 27 | ] 28 | }, 29 | { 30 | type: 'category', 31 | label: 'Standards', 32 | link: { 33 | type: 'doc', 34 | id: 'standards/overview' 35 | }, 36 | items: require('./sidebarsStandardsItems.js') // this file will be generated entirely by `populateStds.js` via npm post-install hook found in the package.json 37 | } 38 | ] 39 | } 40 | 41 | module.exports = sidebars 42 | -------------------------------------------------------------------------------- /user-docs/usage-hints/find-image/find_img2.tf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env tofu apply -auto-approve 2 | # Pass variables with -var os_purpose=minimal 3 | # (c) Kurt Garloff 4 | # SPDX-License-Identifier: MIT 5 | 6 | variable "os_distro2" { 7 | type = string 8 | default = "ubuntu" 9 | } 10 | 11 | variable "os_version2" { 12 | type = string 13 | default = "24.04" 14 | } 15 | 16 | variable "os_purpose2" { 17 | type = string 18 | default = "generic" 19 | } 20 | 21 | #terraform { 22 | # required_providers { 23 | # openstack = { 24 | # source = "terraform-provider-openstack/openstack" 25 | # version = "~> 1.54.0" 26 | # } 27 | # } 28 | #} 29 | 30 | #provider "openstack" { 31 | # # Your cloud config (or use environment variables OS_CLOUD) 32 | #} 33 | 34 | # Call python find_img.py to find best image 35 | data "external" "my_image2" { 36 | program = ["python3", "${path.module}/find_img2.py"] 37 | 38 | query = { 39 | os_distro = "${var.os_distro2}" 40 | os_version = "${var.os_version2}" 41 | os_purpose = "${var.os_purpose2}" 42 | } 43 | } 44 | 45 | # Output the results for inspection 46 | output "selected_image2" { 47 | value = { 48 | id = data.external.my_image2.result.image_id 49 | name = data.external.my_image2.result.image_name 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /community/contribute/linting-guide.md: -------------------------------------------------------------------------------- 1 | # Linting Guide 2 | 3 | In order to have a clean content repository regarding all markdown files we enforce linting on: 4 | 5 | 1. all staged files prior committing 6 | 2. all Pull Requests 7 | 8 | ## Pre Commit 9 | 10 | Run markdownlint against staged git files with Husky git hook: 11 | 12 | 1. [lint-staged](https://github.com/okonet/lint-staged) 13 | 2. [husky](https://github.com/typicode/husky) 14 | 15 | The rules are enforced on markdown files, for which we use: 16 | 17 | 1. [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) for markdownlint 18 | 2. [prettier](https://github.com/prettier/prettier) for code formatting 19 | 20 | The markdownlint rules are defined in the configuration file `.markdownlint-cli2.jsonc` 21 | 22 | Additionally we use [markdownlint-rule-search-replace](https://github.com/OnkarRuikar/markdownlint-rule-search-replace) for fixing 23 | 24 | ## Local Usage for development 25 | 26 | ```bash 27 | npm run lint:md 28 | npm run fix:md 29 | ``` 30 | 31 | ## Github Workflows 32 | 33 | There are two actions running on every Pull Request on the `main` branch. 34 | 35 | 1. `link-validator.yml`is checking every link in markdown files. 36 | 2. `pr-markdownlint.yml`is checking all markdown files regarding to the rules defined within `.markdownlint-cli2.jsonc` 37 | -------------------------------------------------------------------------------- /community/tools/github/branchprotection.md: -------------------------------------------------------------------------------- 1 | # Branch Protection Rules 2 | 3 | To protect our source code from unwanted changes, we enforce the following branch protection rules for all repositories within our [GitHub organization](https://github.com/SovereignCloudStack): 4 | 5 | - Require a pull request before merging into our default branch `main`. 6 | - Require at least one approval before pull requests can be merged. 7 | - Dismiss stale pull request approvals when new commits are pushed 8 | - Require status checks to pass before merging 9 | - Require branches to be up to date before merging 10 | - Status checks that are required: 11 | - [DCO](dco-and-licenses.md) 12 | - Do not allow bypassing the above settings 13 | 14 | The branch protection rules are rolled out by our [`github-manager`](https://github.com/SovereignCloudStack/github-manager) to ensure that all repositories use a consistent set of rules. Should you intend to propose changes to the above rules, please open a pull request against [`orgs/SovereignCloudStack/data.yaml`](https://github.com/SovereignCloudStack/github-manager/blob/main/orgs/SovereignCloudStack/data.yaml). 15 | 16 | Some repositories however do allow that the above rules are bypassed by the organization's owners, especially repositories that are used for public resources such as the website or the weekly digest. 17 | -------------------------------------------------------------------------------- /community/tools/mailinglists.md: -------------------------------------------------------------------------------- 1 | # Mailing Lists 2 | 3 | Together with [matrix](/community/tools/matrix) our mailing lists are central 4 | to our collaboration. Currently there is this set of mailing lists: 5 | 6 | - [SCS Community Announcements](https://scs.sovereignit.de/mailman3/postorius/lists/announce.lists.scs.community/) - This list is intended for announcements only. It is moderated. Everyone can subscribe to this list and if you want to stay in touch with SCS, you should subscribe to this list. You will be autosubscribed if you become a member of the SCS community (see below), but it's not a requirement to be a member. 7 | 8 | - [SCS Tech Community List](https://scs.sovereignit.de/mailman3/postorius/lists/scs-tech.lists.scs.community/) - The overall list for anything related to technical discussions. Everyone can subscribe to this list. Furthermore all members of the Technology Group of the SCS Community are automatically subscribed to this list. You can subscribe also when not being a member. 9 | 10 | - SCS Members - Members of the SCS Community are automatically subscribed to this list. Announcements and discussions regarding the SCS Community are welcome here. This list is members only. 11 | 12 | ## SCS community Membership 13 | 14 | Membership means that you are onboarded to the Identity Management system of our [Nextcloud](nextcloud.md). 15 | -------------------------------------------------------------------------------- /.github/workflows/build_and_deploy.yml: -------------------------------------------------------------------------------- 1 | name: Build and Deploy to Github Pages 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | - cron: "0 5 * * *" 7 | push: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | build_and_deploy: 13 | permissions: 14 | contents: write 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Checkout Repository 18 | uses: actions/checkout@v3 19 | with: 20 | ref: ${{ github.head_ref }} 21 | 22 | - name: Setup Node 23 | uses: actions/setup-node@v3 24 | with: 25 | node-version: 20 26 | 27 | - name: Cache dependencies 28 | uses: actions/cache@v3 29 | with: 30 | path: ~/.npm 31 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} 32 | restore-keys: | 33 | ${{ runner.os }}-node- 34 | 35 | - name: Install dependencies and build page 36 | run: | 37 | npm ci 38 | npm run build 39 | 40 | - name: Deploy 41 | uses: peaceiris/actions-gh-pages@v3 42 | with: 43 | publish_dir: ./build 44 | github_token: ${{ secrets.GITHUB_TOKEN }} 45 | force_orphan: true 46 | user_name: 'github-actions[bot]' 47 | user_email: 'github-actions[bot]@users.noreply.github.com' 48 | commit_message: 'Update SCS Docs Page' 49 | -------------------------------------------------------------------------------- /.github/workflows/build_and_staging.yml: -------------------------------------------------------------------------------- 1 | name: Build and Deploy to staging Branch 2 | 3 | on: 4 | push: 5 | branches: 6 | - staging 7 | workflow_dispatch: 8 | 9 | jobs: 10 | build_and_staging: 11 | permissions: 12 | contents: write 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout Repository 16 | uses: actions/checkout@v3 17 | with: 18 | ref: ${{ github.ref_name }} 19 | 20 | - name: Setup Node 21 | uses: actions/setup-node@v3 22 | with: 23 | node-version: 20 24 | 25 | - name: Cache dependencies 26 | uses: actions/cache@v3 27 | with: 28 | path: ~/.npm 29 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} 30 | restore-keys: | 31 | ${{ runner.os }}-node- 32 | 33 | - name: Install dependencies and build page 34 | run: | 35 | npm ci 36 | npm run build 37 | 38 | - name: Deploy 39 | uses: peaceiris/actions-gh-pages@v3 40 | with: 41 | publish_dir: ./build 42 | github_token: ${{ secrets.GITHUB_TOKEN }} 43 | force_orphan: true 44 | user_name: 'github-actions[bot]' 45 | user_email: 'github-actions[bot]@users.noreply.github.com' 46 | commit_message: 'Update SCS Docs Page' 47 | publish_branch: gh-pages-staging 48 | -------------------------------------------------------------------------------- /sidebarsUserDocs.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ 4 | const sidebars = { 5 | userDocs: [ 6 | 'index', 7 | { 8 | type: 'category', 9 | label: 'Application Examples', 10 | link: { 11 | type: 'generated-index' 12 | }, 13 | items: [ 14 | { 15 | type: 'category', 16 | label: 'openDesk on SCS', 17 | link: { 18 | type: 'generated-index' 19 | }, 20 | items: [ 21 | 'application-examples/opendesk-on-scs/overview', 22 | 'application-examples/opendesk-on-scs/quickstart', 23 | 'application-examples/opendesk-on-scs/requirements', 24 | 'application-examples/opendesk-on-scs/getting_started', 25 | 'application-examples/opendesk-on-scs/configuration', 26 | 'application-examples/opendesk-on-scs/user-import', 27 | 'application-examples/opendesk-on-scs/contribute' 28 | ] 29 | } 30 | ] 31 | }, 32 | { 33 | type: 'category', 34 | label: 'Portability Hints', 35 | link: { 36 | type: 'doc', 37 | id: 'usage-hints/index' 38 | }, 39 | items: [ 40 | 'usage-hints/find-image/index', 41 | 'usage-hints/diskless-flavor/index' 42 | ] 43 | } 44 | ] 45 | } 46 | 47 | module.exports = sidebars 48 | -------------------------------------------------------------------------------- /populateCerts.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch') 2 | const fs = require('fs') 3 | const YAML = require('yaml') 4 | 5 | async function fetchScopeTable(uuid, title, path) { 6 | const response = await fetch( 7 | `https://compliance.sovereignit.cloud/markdown/scope/${uuid}` 8 | ) 9 | var text = await response.text() 10 | text = `# ${title}\n\n${text}` 11 | fs.writeFileSync(path, text, 'utf8') 12 | } 13 | 14 | // how many outdated versions of any scope to include 15 | const MAX_OLD = 1 16 | 17 | const filenames = fs 18 | .readdirSync('standards/') 19 | .filter((fn) => fn.startsWith('scs-') && fn.endsWith('.yaml')) 20 | 21 | const scopes = filenames.map((filename) => { 22 | return { 23 | ...YAML.parseDocument( 24 | fs.readFileSync(`standards/${filename}`, 'utf8') 25 | ).toJSON(), 26 | filename, 27 | id: filename.substring(0, filename.length - 5) 28 | } 29 | }) 30 | 31 | const today = new Date().toISOString().slice(0, 10) 32 | 33 | const sidebarItems = scopes.map((scope) => { 34 | fetchScopeTable(scope.uuid, scope.name, `standards/${scope.id}.md`).catch( 35 | (e) => { 36 | console.log(e) 37 | } 38 | ) 39 | return { 40 | type: 'doc', 41 | label: scope.name, 42 | id: scope.id 43 | } 44 | }) 45 | 46 | var newSidebars = `module.exports = ${JSON.stringify(sidebarItems, null, ' ')}` 47 | fs.writeFileSync('./sidebarsCertificationItems.js', newSidebars, 'utf8') 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SCS Docs Page Readme 2 | 3 | ## Rendered docs 4 | 5 | The rendered docs are on the [SCS Docs Pages](https://docs.scs.community/). 6 | The staging branch gets rendered to the [staging server](https://docs-staging.scs.community/). 7 | Note that there are a few minutes delay due to the way the sync is done. 8 | 9 | ## Licenses 10 | 11 | The content of this repository is published under multiple licenses. 12 | All documentation content files within `docs, dev-docs, standards and community` are licensed under [CC-BY-SA 4.0](LICENSE-DOCS). 13 | All source code of this documentation page is licensed under the [MIT](LICENSE-CODE) license. 14 | 15 | ## Overview 16 | 17 | SCS Docs Page is a static page rendering the markdown content of all Docs regarding SCS. Underlaying engine is [Docusaurus](https://docusaurus.io/), a React based static page generator. 18 | 19 | ## Developing locally 20 | 21 | In order to run the Docs locally, make sure you have node.js and npm installed. 22 | 23 | CD in your Terminal to the root directory of the cloned repository. Install all the dependencies and start the local development server. 24 | 25 | ```bash 26 | npm install 27 | npm start 28 | ``` 29 | 30 | ## Linting problems 31 | 32 | The repository establishes commit hooks which check the files for correctness and style. 33 | Have a look at the [linting-guide](https://docs.scs.community/community/contribute/linting-guide/) to get detailed information. 34 | -------------------------------------------------------------------------------- /.github/workflows/pr-markdownlint.yml: -------------------------------------------------------------------------------- 1 | name: Markdownlint on PR 2 | permissions: 3 | contents: read 4 | 5 | on: 6 | pull_request: 7 | branches: 8 | - main 9 | paths: 10 | - .nvmrc 11 | - "**/*.md" 12 | 13 | jobs: 14 | lint-docs: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | 20 | - name: Get changed files 21 | env: 22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 23 | BASE_SHA: ${{ github.event.pull_request.base.sha }} 24 | HEAD_SHA: ${{ github.event.pull_request.head.sha }} 25 | run: | 26 | # Use the GitHub API to get the list of changed files 27 | # documenation: https://docs.github.com/rest/commits/commits#compare-two-commits 28 | DIFF_DOCUMENTS=$(gh api repos/{owner}/{repo}/compare/${{ env.BASE_SHA }}...${{ env.HEAD_SHA }} \ 29 | --jq '.files | .[] | select(.status|IN("added", "modified", "renamed", "copied", "changed")) | .filename') 30 | # filter out files that are not markdown 31 | DIFF_DOCUMENTS=$(echo "${DIFF_DOCUMENTS}" | egrep -i "^files/.*\.md$" | xargs) 32 | echo "DIFF_DOCUMENTS=${DIFF_DOCUMENTS}" >> $GITHUB_ENV 33 | 34 | - name: Setup Node.js environment 35 | uses: actions/setup-node@v3 36 | with: 37 | node-version-file: ".nvmrc" 38 | cache: npm 39 | cache-dependency-path: package-lock.json 40 | 41 | 42 | - name: Install all npm packages 43 | run: npm install 44 | 45 | - name: Lint markdown files 46 | run: | 47 | npm run lint:md $DIFF_DOCUMENTS 48 | -------------------------------------------------------------------------------- /docs/05-iam/SCS-example-setup-configuration-description.md: -------------------------------------------------------------------------------- 1 | # Example setup configuration in SCS deployment explained 2 | 3 | The following document explains the idea behind the example configuration is done. 4 | The playbook creates a proxy realm used to connect with `Keystone`, a customer realm, the clients needed to connect the realms, the identity brokering for the customer realm, a login flow 5 | to be able to use the `home-IdP-discovery` plugin to redirect to the correct customer realm and an example user. 6 | SCS operators can find the playbook that creates the setup [here](https://github.com/osism/ansible-playbooks/blob/main/playbooks/infrastructure/keycloak-oidc-client-config.yml). 7 | 8 | 1. In the first place a proxy realm called `osism` on the example deployment. That realm will 9 | become the realm that will be conected to `Keystone` 10 | 11 | 2. A customer realm called `CustomerA` is created. On that realm a `OIDC` client is created to hook 12 | up the realm to the proxy realm. This is done via `Identity Brokering` in the proxy realm. 13 | 14 | 3. An `Identity provider` is configured in the `osism` realm, this is configured to be connected to 15 | the `CustomerA` realm. For that, a set of mappers are created, the default ones are a `hardcoded-attribute` 16 | that sets the domain where the user came from, and an `attribute-importer` mapper for the `openstack-default-project` that comes 17 | in the `OIDC` claim from the customer realm. 18 | 19 | 4. A new login flow has been created in the `osism` realm, this login flow is needed to use the `home-IdP-discovery` plugin. 20 | 21 | 5. Creation of an example user called `Alice`. 22 | -------------------------------------------------------------------------------- /contributor-docs/operations/iam/identity-federation-in-scs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Identity Federation in SCS 3 | type: 4 | status: Draft 5 | track: Global 6 | --- 7 | 8 | SovereignCloudStack wants to make it possible for operators to delegate 9 | administration of user identities to the organizational entities that the 10 | users are part of. Usually that's customer organizations but it could also 11 | be the operator itself. Federation protocols like OpenID Connect can be used 12 | to achieve that goal. To simplify connecting the different parts of SCS 13 | to customer owned IAM solutions, SCS deploys Keycloak as central Identity 14 | Provider (IdP) service. 15 | 16 | Currently this is deployed automatically only in the [osism/testbed](https://docs.scs.community/docs/iaas/guides/deploy-guide/examples/testbed/), 17 | which provides [its own documentation for authentication with OIDC](https://docs.scs.community/docs/iaas/guides/deploy-guide/examples/testbed#authentication-with-oidc). 18 | 19 | The following sections describe how this is done. 20 | 21 | ## 1. IaaS / OpenStack 22 | 23 | To provide Infrastrucure as a Service SCS builds upon 24 | OpenStack. See section [OpenStack Federation via OpenID-Connect](https://docs.scs.community/dev-docs/operations/iam/openstack-federation-via-oidc) 25 | for more details on identity federation for OpenStack. 26 | 27 | ## 2. CaaS 28 | 29 | To provide Container as a Service SCS builds upon 30 | Kubernetes. There is 31 | [work in progress](https://github.com/SovereignCloudStack/issues/issues/373) 32 | to optionally connect Kubernetes to Keycloak and to 33 | map authorization decisions based on claims via cluster role bindings. 34 | -------------------------------------------------------------------------------- /community/tools/zuul.md: -------------------------------------------------------------------------------- 1 | # Zuul 2 | 3 | ## Zuul CI/CD pipelines and project gating 4 | 5 | Since we are expecting a lot of pipelines beeing created and used GitHub actions won't keep up 6 | well. We also expect cross-repository and even cross-project dependencies. Therefore we decided to 7 | use Zuul as our main pipeline solution. 8 | 9 | ### How to make a repo use Zuul 10 | 11 | - Make Zuul aware of your repository in this [repo](https://github.com/SovereignCloudStack/zuul_deployment) 12 | - Create a file _.zuul.yaml_ 13 | - An example can be found [here](https://github.com/SovereignCloudStack/zuul-sandbox/blob/main/.zuul.yaml) 14 | - You can have a job section containing _self-defined_ jobs which you need to write on your own 15 | - You have to have a project section containing 16 | - the default-branch name 17 | - the merge-mode which should be used to auto-merge 18 | - the jobs to run in each pipeline (gh_check, gh_gate, gh_post, gh_tag) 19 | - these pipelines are triggered by events which can be looked up [here](https://github.com/SovereignCloudStack/zuul_config/blob/main/zuul.d/gh_pipelines.yaml) 20 | - some default jobs can be found [here](https://opendev.org/zuul/zuul-jobs/src/branch/master/playbooks) 21 | - If you have _self-defined_ jobs, you need to create a folder _.playbooks_ 22 | - this folder containers ansible playbooks which will be triggered 23 | 24 | ### General information about Zuul 25 | 26 | Zuul does not take anything for granted. If you need to have something installed, 27 | you should install it via ansible. Our test-machines are basically pimped 28 | docker-containers, so we might run into issues some time. But for now, things work pretty good. 29 | -------------------------------------------------------------------------------- /community/governance/project-board.md: -------------------------------------------------------------------------------- 1 | # The SCS Project Board 2 | 3 | The governance of the community is described in the procedural standard [SCS-0005](https://docs.scs.community/standards/global/scs-0005). 4 | The SCS Project Board can be reached via e-mail: [project-board@lists.scs.community](mailto:project-board@lists.scs.community). 5 | 6 | ## Project Board Term 2025 7 | 8 | For the term 2025 the project board consists of: 9 | 10 | Spokesperson: Felix Kronlage-Dammers, @fkr 11 | 12 | | Name, Firstname | Github Handle | E-Mail | Remark | 13 | | ----------------------- | ---------------------------------------------- | ------------------------------------------------------------ |--------------------------------- 14 | | Berendt, Christian | [@berendt](https://github.com/berendt) | [berendt@osism.tech](mailto:berendt@osism.tech) | Elected by Community | 15 | | Feder, Matej | [@matofeder](https://github.com/matofeder) | [matej.feder@dnation.cloud](mailto:matej.feder@dnation.cloud)| Elected by Community | 16 | | Garloff, Kurt | [@garloff](https://github.com/garloff) | [scs@garloff.de](mailto:scs@garloff.de) | Elected by Community | 17 | | Kronlage-Dammers, Felix | [@fkr](https://github.com/fkr) | [fkr@osb-alliance.com](mailto:fkr@osb-alliance.com) | Represents Forum SCS-Standards | 18 | | Schoone, Jan | [@jschoone](https://github.com/jschoone) | [jan.schoone@uhurutec.com](mailto:jan.schoone@uhurutec.com) | Elected by Community | 19 | -------------------------------------------------------------------------------- /community/collaboration/index.mdx: -------------------------------------------------------------------------------- 1 | import CommunityCalendar from '../../src/components/CommunityCalendar' 2 | 3 | # Collaboration 4 | 5 | ## We’re an open community 6 | 7 | Our meetings are publicly announced and we are happy to welcome both newcomers and established members alike. You can navigate either through the calendar below or subscribe with your favorite client to https://sovereigncloudstack.github.io/calendar/scs.ics. The calendar is collaboratively maintained on GitHub and new entries, such as a lightning talk, are highly appreciated! 8 | 9 | 10 | 11 | ## Collaborating with issues and pull requests 12 | 13 | We use the GitHub flow to track and discuss changes in issues, then propose and 14 | review changes in pull requests. See the 15 | [GitHub documentation](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests) 16 | for more details. 17 | 18 | ## Meetings 19 | 20 | ### Project updates 21 | 22 | - Weekly with all teams on Thursday at 15:05 CEST (40 mins) 23 | - In some weeks we schedule an additional lightning talk at 15:40 CEST 24 | 25 | ### Sprint review/Backlog refinement/Sprint planning meetings 26 | 27 | - Weekly Team meetings (~1hr) for currently 4 teams: 28 | - Team IaaS 29 | - Team Container 30 | - Team IAM & Security 31 | - Team Operations 32 | - Please refer to the public calendar above for details. 33 | 34 | ### Special interest groups (SIGs) and hacking sessions 35 | 36 | - There are a number of SIG meetings and hacking sessions that meet weekly or bi-weekly 37 | - SIG Monitoring and Logging 38 | - SIG Standardization and Certification 39 | - SIG Documentation 40 | - SIG Community 41 | - SIG Central API 42 | - Please refer to the public calendar above for details. 43 | -------------------------------------------------------------------------------- /community/central-services/plusserver-gx-scs.md: -------------------------------------------------------------------------------- 1 | # Central services 2 | 3 | This document gives an overview of what SCS central services are deployed and who is responsible for them in plusserver gx-scs infrastructure. 4 | 5 | ## Project p500924-harbor 6 | 7 | ### K8s clusters 8 | 9 | #### Harbor 10 | 11 | Responsibility: [@SovereignCloudStack/vp06c](https://github.com/orgs/SovereignCloudStack/teams/vp06c) 12 | 13 | Services: 14 | 15 | - [SCS Registry](https://registry.scs.community/) 16 | - [k8s-harbor](https://github.com/SovereignCloudStack/k8s-harbor/tree/main/envs/public) 17 | 18 | Utilization: 19 | 20 | - Instances: 7 21 | - VCPUs: 32 22 | - RAM: 64GB 23 | 24 | Spec: 25 | 26 | - version: v7.0.0 - R6 27 | - management cluster: 28 | - 1 instance: SCS-2V:4:20 29 | - image: Ubuntu 22.04 (20230416) 30 | - k8s: v1.25.3 - KinD 31 | - workload cluster: 32 | - 6 instances: 33 | - 3 control-planes: SCS-2V-4-20s 34 | - 3 workers: SCS-8V:16:100 35 | - image: ubuntu-capi-image-v1.28.7 36 | - k8s: v1.28.7 37 | 38 | ## Project p500924-sig-monitoring1 39 | 40 | ### K8s clusters 41 | 42 | #### Monitoring 43 | 44 | Responsibility: [@SovereignCloudStack/vp06c](https://github.com/orgs/SovereignCloudStack/teams/vp06c) 45 | 46 | Services: 47 | 48 | - [k8s-observability](https://github.com/SovereignCloudStack/k8s-observability) 49 | 50 | Utilization: 51 | 52 | - Instances: 7 53 | - VCPUs: 32 54 | - RAM: 64GB 55 | 56 | Spec: 57 | 58 | - version: v7.0.0 - R6 59 | - management cluster: 60 | - 1 instance: SCS-2V:4:20 61 | - image: Ubuntu 22.04 (20240125) 62 | - k8s: v1.27.3 - KinD 63 | - workload cluster: 64 | - 6 instances: 65 | - 3 control-planes: SCS-2V-4-20s 66 | - 3 workers: SCS-8V:16:100 67 | - image: ubuntu-capi-image-v1.28.7 68 | - k8s: v1.28.7 69 | -------------------------------------------------------------------------------- /src/components/CalendarModal.tsx: -------------------------------------------------------------------------------- 1 | import { preventDefault } from "@fullcalendar/core/internal"; 2 | import React from "react"; 3 | import Button from "./Button"; 4 | import styles from "./calendarModal.module.css"; 5 | 6 | interface CalendarModalProps { 7 | calendarEvent: any; 8 | onClose: () => void; 9 | show: boolean; 10 | } 11 | 12 | const CalendarModal: React.FunctionComponent = (props) => { 13 | const { calendarEvent, onClose, show } = props; 14 | 15 | const joinEvent = (e) => { 16 | e.stopPropagation(); 17 | }; 18 | 19 | return ( 20 | <> 21 | {show && calendarEvent && ( 22 |
23 |
24 |
25 |

26 | {calendarEvent.title} 27 |

28 |
29 |
30 |

{calendarEvent.extendedProps.description}

31 |

{calendarEvent.extendedProps.location}

32 |
33 |
39 |
40 |
41 |
42 | )} 43 | 44 | ); 45 | }; 46 | 47 | export default CalendarModal; 48 | -------------------------------------------------------------------------------- /.markdownlint-cli2.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "default": true, 4 | "MD013": false, 5 | "MD033": { "allowed_elements": ["li", "ul"] }, // only allowing ul, li elements for checkboxes within md tables 6 | "MD024": false, 7 | "relative-links": false, 8 | "search-replace": { 9 | "rules": [ 10 | { 11 | "name": "curly-double-quotes", 12 | "message": "Don't use curly double quotes", 13 | "searchPattern": "/“|”/g", 14 | "replace": "\"", 15 | "skipCode": true 16 | }, 17 | { 18 | "name": "curly-single-quotes", 19 | "message": "Don't use curly single quotes", 20 | "searchPattern": "/‘|’/g", 21 | "replace": "'", 22 | "skipCode": true 23 | }, 24 | { 25 | "name": "m-dash", 26 | "message": "Don't use '--'. Use m-dash — instead", 27 | "search": " -- ", 28 | "replace": " — ", 29 | "skipCode": true 30 | }, 31 | { 32 | "name": "relative-link-path", 33 | "message": "Don't use relative paths", 34 | "search": "](..", 35 | "skipCode": true 36 | }, 37 | { 38 | "name": "trailing-spaces", 39 | "message": "Avoid trailing spaces", 40 | "searchPattern": "/ +$/gm", 41 | "replace": "", 42 | "skipCode": false 43 | }, 44 | { 45 | "name": "double-spaces", 46 | "message": "Avoid double spaces", 47 | "searchPattern": "/([^\\s>]) ([^\\s|])/g", 48 | "replace": "$1 $2", 49 | "skipCode": true 50 | } 51 | ] 52 | } 53 | }, 54 | "customRules": [ 55 | "markdownlint-rule-search-replace", 56 | "markdownlint-rule-relative-links" 57 | ], 58 | "ignores": ["node_modules", ".github", "docs", "standards"], 59 | "globs": ["**/*.{md}"] 60 | } 61 | -------------------------------------------------------------------------------- /user-docs/usage-hints/find-image/find_img.tf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env tofu apply -auto-approve 2 | # Pass variables with -var os_purpose=minimal 3 | # (c) Kurt Garloff 4 | # SPDX-License-Identifier: MIT 5 | 6 | variable "os_distro" { 7 | type = string 8 | default = "ubuntu" 9 | } 10 | 11 | variable "os_version" { 12 | type = string 13 | default = "24.04" 14 | } 15 | 16 | variable "os_purpose" { 17 | type = string 18 | default = "generic" 19 | } 20 | 21 | terraform { 22 | required_providers { 23 | openstack = { 24 | source = "terraform-provider-openstack/openstack" 25 | version = "~> 1.54.0" 26 | } 27 | } 28 | } 29 | 30 | provider "openstack" { 31 | # Your cloud config (or use environment variable OS_CLOUD) 32 | } 33 | 34 | data "openstack_images_image_v2" "my_image" { 35 | most_recent = true 36 | 37 | properties = { 38 | os_distro = "${var.os_distro}" 39 | os_version = "${var.os_version}" 40 | os_purpose = "${var.os_purpose}" 41 | } 42 | #sort = "name:desc,created_at:desc" 43 | #sort_key = "name" 44 | #sort_direction = "desc" 45 | } 46 | 47 | # Output the results for inspection 48 | output "selected_image_id" { 49 | value = data.openstack_images_image_v2.my_image.id 50 | } 51 | 52 | output "selected_image_name" { 53 | value = data.openstack_images_image_v2.my_image.name 54 | } 55 | 56 | output "selected_image_created_at" { 57 | value = data.openstack_images_image_v2.my_image.created_at 58 | } 59 | 60 | output "selected_image_properties" { 61 | value = { 62 | os_distro = data.openstack_images_image_v2.my_image.properties.os_distro 63 | os_version = data.openstack_images_image_v2.my_image.properties.os_version 64 | os_purpose = data.openstack_images_image_v2.my_image.properties.os_purpose 65 | } 66 | } 67 | 68 | output "selected_image_tags" { 69 | value = data.openstack_images_image_v2.my_image.tags 70 | } 71 | 72 | -------------------------------------------------------------------------------- /getDocs.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const { execSync } = require('child_process') 3 | 4 | // Read the contents of the "docs.package.json" file and remove all whitespace 5 | const reposJson = fs 6 | .readFileSync('./docs.package.json', 'utf8') 7 | .replace(/\s/g, '') 8 | 9 | // Parse the JSON and create an array of repositories 10 | const repos = JSON.parse(reposJson) 11 | const ghUrl = 'https://github.com/' 12 | 13 | // Clone each repository, remove git folders and README files, and copy the docs to the target directory 14 | repos.forEach((repo) => { 15 | const repoDir = `repo_to_be_edited/${repo.label}` 16 | 17 | // Clone the repository 18 | const cloneCommand = `git clone ${ghUrl + repo.repo} ${repoDir}` 19 | execSync(cloneCommand) 20 | 21 | // Remove git folders 22 | const removeGitCommand = `rm -rf ${repoDir}/.git` 23 | execSync(removeGitCommand) 24 | 25 | // Remove README files 26 | const removeReadmeCommand = `find ${repoDir} -name "README.md" | xargs rm -f` 27 | execSync(removeReadmeCommand) 28 | 29 | // Create the docusaurus subdirectory 30 | const subDirPath = `${repo.target}/${repo.label}` 31 | fs.mkdirSync(subDirPath, { recursive: true }) 32 | 33 | // Copy docs content from A to B 34 | // allow multiple sources here so the same repo need not be checked out multiple times 35 | // however, it would be better if this script automatically grouped all entries by repo and then only 36 | // checked out each repo only once; I leave this as a TODO because I don't fully grasp the meaning of 37 | // label, for instance, and the label is used for the temporary repo directory 38 | let sources = Array.isArray(repo.source) ? repo.source : [repo.source] 39 | sources.forEach((source) => { 40 | const copyDocsCommand = `cp -r ${repoDir}/${source} ${subDirPath}` 41 | execSync(copyDocsCommand) 42 | }) 43 | 44 | // Remove the cloned repository 45 | const removeRepoCommand = 'rm -rf repo_to_be_edited' 46 | execSync(removeRepoCommand) 47 | }) 48 | -------------------------------------------------------------------------------- /docs/05-iam/iaas-roles.md: -------------------------------------------------------------------------------- 1 | # IaaS Roles 2 | 3 | An SCS-compliant cloud offers the following roles on the Infrastructure as a Service (IaaS) layer: 4 | 5 | | Role | Scope | Description | 6 | |---|---|---| 7 | | reader | All OpenStack APIs | Role with read-only access within authentication scope. | 8 | | member | All OpenStack APIs | Role with read-write access within authentication scope. | 9 | | manager | Identity API | Role with self-service capabilites for the Identity API in domain scope. | 10 | | admin | All OpenStack APIs | Most privileged role, reserved for CSP personnel, to administer the OpenStack cloud | 11 | 12 | :::info Role Inheritance 13 | 14 | The OpenStack Identity API implements automatic role inheritance between admin, manager, member and reader roles where a role with higher privileges inherits all lesser roles automatically. 15 | 16 | This means: 17 | 18 | - `admin` inherits `manager`, `member` and `reader` 19 | - `manager` inherits `member` and `reader` 20 | - `member` inherits `reader` 21 | 22 | ::: 23 | 24 | ## Role Assignment 25 | 26 | ### Scopes & Targets 27 | 28 | Roles can be assigned in different scopes and either to users or groups. 29 | This leads to the following role assignment matrix: 30 | 31 | | | User | Group | 32 | |---|---|---| 33 | | Project | single user, permissions in project | all users of group, permissions in project | 34 | | Domain | single user, permissions in domain | all users of group, permissions in domain | 35 | | System | single user, permissions in whole cloud | all users of group, permissions in whole cloud | 36 | 37 | (rows are the scopes and columns are the role assignment target entities) 38 | 39 | ### Assignment Procedure 40 | 41 | Roles are assigned to users or groups by administrative personnel. 42 | In most cases, this is either: 43 | 44 | - a cloud operator with the admin role, belonging to the provider 45 | - a domain manager with the manager role in domain scope, belonging to the provider or a tenant 46 | 47 | A domain manager can only assign and revoke roles within their own domain and is restricted to a specific subset of available roles to prevent privilege escalation. 48 | -------------------------------------------------------------------------------- /src/components/contentcard.module.css: -------------------------------------------------------------------------------- 1 | .link { 2 | text-decoration: none; 3 | } 4 | 5 | .button { 6 | background-color: #50c3a5; /* Green */ 7 | border: none; 8 | color: white; 9 | padding: 15px 32px; 10 | text-align: center; 11 | text-decoration: none; 12 | display: inline-block; 13 | font-size: 16px; 14 | border-radius: 8px; 15 | font-weight: 600; 16 | cursor: pointer; 17 | } 18 | 19 | .button:hover { 20 | background-color: #0f5fe1; /* Green */ 21 | } 22 | 23 | @media only screen and (min-width: 996px) { 24 | .card { 25 | height: 100%; 26 | } 27 | } 28 | 29 | .contentCard { 30 | border: solid #666 2px; 31 | box-shadow: 2px 2px 4px 4px rgba(10, 10, 10, 0.1); 32 | } 33 | 34 | .layerComponent { 35 | border: solid 2px rgba(70, 72, 213, 0.539); 36 | border-radius: 4px; 37 | background: #43d8b24f; 38 | width: 80px; 39 | height: 80px; 40 | margin: 0 0 8px 8px; 41 | padding: 8px; 42 | font-weight: 600; 43 | font-size: 10px; 44 | text-decoration: none; 45 | color: black; 46 | } 47 | 48 | .layerComponentWip { 49 | border: dashed 2px rgba(70, 72, 213, 0.539); 50 | border-radius: 4px; 51 | width: 80px; 52 | height: 80px; 53 | margin: 0 0 8px 8px; 54 | padding: 8px; 55 | font-size: 10px; 56 | text-decoration: none; 57 | color: black; 58 | background-image: repeating-linear-gradient( 59 | 45deg, 60 | white 0%, 61 | white 2%, 62 | #43d8b24f 2%, 63 | #43d8b24f 4%, 64 | white 4% 65 | ); 66 | } 67 | 68 | .layerComponentWip:hover, 69 | .layerComponent:hover { 70 | color: blue; 71 | text-decoration: none !important; 72 | background-color: #43d8b22f; 73 | } 74 | 75 | .chipOptional { 76 | font-size: 8px; 77 | border-radius: 8px; 78 | padding: 2px 4px 2px 4px; 79 | background-color: #892be27b; 80 | text-align: center; 81 | max-width: fit-content; 82 | margin: 2px 2px 0 0; 83 | color: #000; 84 | } 85 | 86 | .chipMandatory { 87 | font-size: 8px; 88 | border-radius: 8px; 89 | padding: 2px 4px 2px 4px; 90 | background-color: #e2a82b94; 91 | text-align: center; 92 | max-width: fit-content; 93 | margin: 2px 2px 0 0; 94 | color: #000; 95 | } 96 | -------------------------------------------------------------------------------- /src/components/CommunityCalendar.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import FullCalendar from "@fullcalendar/react"; 3 | import dayGridPlugin from "@fullcalendar/daygrid"; 4 | import timeGridPlugin from "@fullcalendar/timegrid"; 5 | import interactionPlugin from "@fullcalendar/interaction"; 6 | import icalendarPlugin from "@fullcalendar/icalendar"; 7 | import CalendarModal from "./CalendarModal"; 8 | 9 | const CommunityCalendar: React.FunctionComponent = () => { 10 | const [showModal, setShowModal] = useState(false); 11 | const [calendarEvent, setCalendarEvent] = useState(); 12 | 13 | const showEventInfo = (info) => { 14 | setShowModal(!showModal); 15 | setCalendarEvent(info.event); 16 | }; 17 | 18 | return ( 19 | <> 20 | showEventInfo(info)} 29 | plugins={[ 30 | dayGridPlugin, 31 | timeGridPlugin, 32 | icalendarPlugin, 33 | interactionPlugin, 34 | ]} 35 | initialView="timeGridWeek" 36 | weekends={false} 37 | events={{ 38 | url: "https://sovereigncloudstack.github.io/calendar/scs.ics", 39 | format: "ics", 40 | }} 41 | headerToolbar={{ 42 | left: "prev,next today", 43 | center: "title", 44 | right: "timeGridDay,timeGridWeek,dayGridMonth", 45 | }} 46 | /> 47 |
48 | setShowModal(false)} 52 | /> 53 |
54 | 55 | ); 56 | }; 57 | 58 | export default CommunityCalendar; 59 | -------------------------------------------------------------------------------- /community/contribute/styleguide.md: -------------------------------------------------------------------------------- 1 | # Styleguide 2 | 3 | ## Admonitions 4 | 5 | We adopt the default Admonition colors for Note, Tip, Info, Caution, Danger by docusaurus: 6 | 7 | [Docusaurus Admonitons](https://docusaurus-archive-october-2023.netlify.app/docs/markdown-features/admonitions) 8 | 9 | :::note 10 | 11 | Some **content** with _Markdown_ `syntax`. 12 | 13 | ::: 14 | 15 | :::tip 16 | 17 | Some **content** with _Markdown_ `syntax`. 18 | 19 | ::: 20 | 21 | :::info 22 | 23 | Some **content** with _Markdown_ `syntax`. 24 | 25 | ::: 26 | 27 | :::caution 28 | 29 | Some **content** with _Markdown_ `syntax`. 30 | 31 | ::: 32 | 33 | :::danger 34 | 35 | Some **content** with _Markdown_ `syntax`. 36 | 37 | ::: 38 | 39 | ## Blockquotes 40 | 41 | Blockquotes should be handled with standard markdown `>` 42 | 43 | Example Blockquote: 44 | 45 | > The raw data format is really the only sensible format option to use with RBD. asdasdasdasd asd asd a 46 | > Technically, you could use other QEMU-supported formats 47 | > (such as qcow2 or vmdk), but doing so would add additional overhead, and would 48 | > also render the volume unsafe for virtual machine live 49 | > migration when caching (see below) is enabled. 50 | 51 | ## Codeblocks 52 | 53 | We support markdown language features for Codeblocks. 54 | It is mandatory to define the language to be quoted, when using codeblocks. 55 | Syntax Highlighting is also supported by [Docusaurus via Prism](https://docusaurus-archive-october-2023.netlify.app/docs/markdown-features/code-blocks#supported-languages). 56 | We are using the GitHub language themeing as default. 57 | 58 | ```python title="Python example" 59 | def code_block(): 60 | # Everything in this function is part of the same code block 61 | print (1) 62 | print (2) 63 | 64 | for i in range(4): 65 | # Everyting in this loop is part of the same code block 66 | print (i) 67 | ``` 68 | 69 | ```javascript title="Javascript example" 70 | const code_block = () => { 71 | console.log('inside code_block') 72 | } 73 | ``` 74 | 75 | ```yaml title="YAML example" 76 | --- 77 | doe: 'a deer, a female deer' 78 | ray: 'a drop of golden sun' 79 | pi: 3.14159 80 | xmas: true 81 | french-hens: 3 82 | calling-birds: 83 | - huey 84 | - dewey 85 | - louie 86 | - fred 87 | ``` 88 | 89 | ```ruby title="Ruby example" 90 | require 'redcarpet' 91 | markdown = Redcarpet.new("Hello World!") 92 | puts markdown.to_html 93 | ``` 94 | -------------------------------------------------------------------------------- /src/components/ContentCard.tsx: -------------------------------------------------------------------------------- 1 | import React, { CSSProperties } from 'react' 2 | import styles from './contentcard.module.css' 3 | import Link from '@docusaurus/Link' 4 | import { useLocation } from '@docusaurus/router' 5 | 6 | interface LayerComponent { 7 | title: string 8 | url: string 9 | mandatory: string 10 | stable: string 11 | } 12 | 13 | interface ContentCardProps { 14 | style?: React.CSSProperties 15 | title: string 16 | body: string 17 | url: string 18 | buttonText: string 19 | small?: boolean 20 | components?: LayerComponent[] 21 | } 22 | 23 | const ContentCard: React.FunctionComponent = (props) => { 24 | const { title, body, url, buttonText, style, small, components } = props 25 | 26 | const location = useLocation() 27 | 28 | return ( 29 |
30 |
31 | {small ? ( 32 |
{title}
33 | ) : ( 34 |

{title}

35 | )} 36 |
37 |
38 |

{body}

39 |
40 |
41 | {components && 42 | components.map((component, index) => ( 43 | 44 |
58 | {component.title} 59 | {/* {component.mandatory == 'true' ? ( 60 |
mandatory
61 | ) : ( 62 |
optional
63 | )} */} 64 |
65 | 66 | ))} 67 |
68 | {buttonText && ( 69 |
70 | 71 | {buttonText} 72 | 73 |
74 | )} 75 |
76 | ) 77 | } 78 | 79 | export default ContentCard 80 | -------------------------------------------------------------------------------- /sidebarsCommunity.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ 4 | const sidebars = { 5 | community: [ 6 | 'index', 7 | 'mission-statement', 8 | 'license-considerations', 9 | { 10 | type: 'category', 11 | link: { 12 | type: 'doc', 13 | id: 'governance/index' 14 | }, 15 | label: 'Governance', 16 | items: [ 17 | 'governance/project-board' 18 | ] 19 | }, 20 | { 21 | type: 'category', 22 | link: { 23 | type: 'doc', 24 | id: 'collaboration/index' 25 | }, 26 | label: 'Collaboration', 27 | items: [ 28 | 'collaboration/team-iaas', 29 | 'collaboration/team-iam', 30 | 'collaboration/team-container', 31 | 'collaboration/team-ops', 32 | 'collaboration/sig-central-api', 33 | 'collaboration/sig-community', 34 | 'collaboration/sig-documentation', 35 | 'collaboration/sig-monitoring', 36 | 'collaboration/sig-standardization' 37 | ] 38 | }, 39 | { 40 | type: 'category', 41 | label: 'Tools', 42 | link: { 43 | type: 'generated-index' 44 | }, 45 | items: [ 46 | 'tools/jitsi', 47 | 'tools/matrix', 48 | 'tools/mailinglists', 49 | 'tools/nextcloud', 50 | 'tools/zuul', 51 | , 52 | { 53 | type: 'category', 54 | label: 'GitHub', 55 | items: [ 56 | 'tools/github/branchprotection', 57 | 'tools/github/dco-and-licenses', 58 | 'tools/github/tips-and-tricks' 59 | ] 60 | }, 61 | { 62 | type: 'category', 63 | label: 'Cloud Resources', 64 | items: [ 65 | 'cloud-resources/cloud-resources', 66 | 'cloud-resources/getting-started-openstack', 67 | 'cloud-resources/plusserver-gx-scs', 68 | 'cloud-resources/wavestack' 69 | ] 70 | } 71 | ] 72 | }, 73 | { 74 | type: 'category', 75 | label: 'Contribute to Docs', 76 | link: { 77 | type: 'generated-index' 78 | }, 79 | items: [ 80 | 'contribute/adding-docs-guide', 81 | 'contribute/doc-files-structure-guide', 82 | 'contribute/docs-workflow-explanation', 83 | 'contribute/linting-guide', 84 | 'contribute/local-docusaurus-development-guide', 85 | 'contribute/styleguide' 86 | ] 87 | } 88 | ] 89 | } 90 | 91 | module.exports = sidebars 92 | -------------------------------------------------------------------------------- /community/contribute/docs-workflow-explanation.md: -------------------------------------------------------------------------------- 1 | # Documentation workflow explanation 2 | 3 | The aim within this documentation is to have a good developer experience and a low entry barrier to start with SCS. For this to achieve we think all docs that define the SCS stack and have been developed by the SCS community should be within this documentation framework. 4 | 5 | ## Information Architecture 6 | 7 | - All general docs are located within the [SovereignCloudStack/docs](https://github.com/SovereignCloudStack/docs) repository. 8 | 9 | - Docs that explain, guide or contextualize specific modules such as the openstack-image-manager or the k8s-cluster-api-provider reside within their repository in a seperate docs directory. 10 | 11 | Both, the general docs and docs of the external repositories are combined into the one unified documentation collection that is being rendered in a static page on [https://docs.scs.community](https://docs.scs.community). In order to make this work we have developed a workflow that syncs all doc repositories and distills only the relevant markdown files. 12 | 13 | The script is called `getDocs`. It is a postinstall script and is executed after `npm install`. This has the advantage to have the docs – coming from the cloud – in your local docusaurus development environment as well as in the build process. 14 | 15 | You'll find the script in the root directory of the [SovereignCloudStack/docs-page](https://github.com/SovereignCloudStack/docs-page) repository: 16 | 17 | ```js title="getDocs.js" 18 | const fs = require('fs') 19 | const { execSync } = require('child_process') 20 | 21 | // Read the contents of the "docs.package.json" file and remove all whitespace 22 | const reposJson = fs 23 | .readFileSync('./docs.package.json', 'utf8') 24 | .replace(/\s/g, '') 25 | 26 | // Parse the JSON and create an array of repositories 27 | const repos = JSON.parse(reposJson) 28 | const ghUrl = 'https://github.com/' 29 | 30 | // Clone each repository, remove git folders and README files, and copy the docs to the target directory 31 | repos.forEach((repo) => { 32 | const repoDir = `repo_to_be_edited/${repo.label}` 33 | 34 | // Clone the repository 35 | const cloneCommand = `git clone ${ghUrl + repo.repo} ${repoDir}` 36 | execSync(cloneCommand) 37 | 38 | // Remove git folders 39 | const removeGitCommand = `rm -rf ${repoDir}/.git` 40 | execSync(removeGitCommand) 41 | 42 | // Remove README files 43 | const removeReadmeCommand = `find ${repoDir} -name "README.md" | xargs rm -f` 44 | execSync(removeReadmeCommand) 45 | 46 | // Create the docusaurus subdirectory 47 | const subDirPath = `${repo.target}/${repo.label}` 48 | fs.mkdirSync(subDirPath, { recursive: true }) 49 | 50 | // Copy docs content from A to B 51 | const copyDocsCommand = `cp -r ${repoDir}/${repo.source} ${subDirPath}` 52 | execSync(copyDocsCommand) 53 | 54 | // Remove the cloned repository 55 | const removeRepoCommand = 'rm -rf repo_to_be_edited' 56 | execSync(removeRepoCommand) 57 | }) 58 | ``` 59 | -------------------------------------------------------------------------------- /community/contribute/local-docusaurus-development-guide.mdx: -------------------------------------------------------------------------------- 1 | import Tabs from '@theme/Tabs' 2 | import TabItem from '@theme/TabItem' 3 | 4 | # Installation 5 | 6 | This Guide shows you how to setup docusaurus on your local machine to run this docs in your local development enviroment. 7 | 8 | ## Requirements 9 | 10 | - git 11 | - Node.js v16 12 | 13 | ## Installation Guide 14 | 15 | ### Step 1 – Installing Node.js via nvm 16 | 17 | It is recommended to install Node.js via nvm – a node version manager – to have the possibility to switch between different node.js versions. 18 | 19 | 20 | 21 | 22 | You must have macOS desktop access with administrator privileges. 23 | 24 | Login to the macOS desktop system and [install Homebrew](https://brew.sh/) on your system (if not already installed). 25 | 26 | Install nvm via homebrew: 27 | 28 | ``` 29 | brew install nvm 30 | ``` 31 | 32 | 33 | 34 | 35 | See [this](https://github.com/nvm-sh/nvm#installing-and-updating) installation guide on GitHub by nvm-sh for installing nvm. 36 | 37 | 38 | 39 | 40 | [NVM for Windows](https://github.com/coreybutler/nvm-windows) 41 | runs in an Admin shell. You'll need to start powershell or Command Prompt as Administrator to use nvm-windows. Install NVM for Windows with an Installer provided by nvm-sh on their [release page](https://github.com/coreybutler/nvm-windows/releases). 42 | 43 | 44 | 45 | 46 | Once installed you can check the available versions with 47 | 48 | ``` 49 | nvm list 50 | ``` 51 | 52 | If you have no other projects, where you need a different version, it is recommended to install the latest stable LTS version of node. 53 | 54 | ```console 55 | nvm install lts 56 | ``` 57 | 58 | nvm has now installed the latest node.js version with its package manager npm. Check if the installation has been successfull by checking it: 59 | 60 | ```console 61 | node --version 62 | ``` 63 | 64 | ### Step 2 – Cloning the repository 65 | 66 | Clone the [docs](https://github.com/SovereignCloudStack/docs) repository via your favourite method: 67 | 68 | 69 | 70 | 71 | ```console title="HTTPS" 72 | git clone https://github.com/SovereignCloudStack/docs.git 73 | ``` 74 | 75 | 76 | 77 | 78 | ```console title="SSH" 79 | git clone git@github.com:SovereignCloudStack/docs.git 80 | ``` 81 | 82 | 83 | 84 | 85 | ### Step 3 – Installing dependencies 86 | 87 | Change your working directory within your terminal to the root of the cloned repository `/docs` and install all dependencies: 88 | 89 | ```console 90 | npm install 91 | ``` 92 | 93 | ### Step 4 – Starting the development server 94 | 95 | You can now run the local development server from your terminal: 96 | 97 | ```console 98 | npm start 99 | ``` 100 | 101 | Once the server is up and running, your terminal will show you the local URL which you can open with your browser to see the page. 102 | -------------------------------------------------------------------------------- /community/tools/github/dco-and-licenses.md: -------------------------------------------------------------------------------- 1 | # Developer Certificate of Origin + Licenses 2 | 3 | The Developer Certificate of Origin (DCO) is a lightweight way for contributors 4 | to certify that they wrote or otherwise have the right to submit the code they 5 | are contributing to the Sovereign Cloud Stack. 6 | 7 | ```bash 8 | By making a contribution to this project, I certify that: 9 | 10 | (a) The contribution was created in whole or in part by me and I 11 | have the right to submit it under the open source license 12 | indicated in the file; or 13 | 14 | (b) The contribution is based upon previous work that, to the best 15 | of my knowledge, is covered under an appropriate open source 16 | license and I have the right under that license to submit that 17 | work with modifications, whether created in whole or in part 18 | by me, under the same open source license (unless I am 19 | permitted to submit under a different license), as indicated 20 | in the file; or 21 | 22 | (c) The contribution was provided directly to me by some other 23 | person who certified (a), (b) or (c) and I have not modified 24 | it. 25 | 26 | (d) I understand and agree that this project and the contribution 27 | are public and that a record of the contribution (including all 28 | personal information I submit with it, including my sign-off) is 29 | maintained indefinitely and may be redistributed consistent with 30 | this project or the open source license(s) involved. 31 | ``` 32 | 33 | All contributions to the Sovereign Cloud Stack are licensed under the 34 | (OSI approved) open source license of the upstream project being used therein 35 | (very often this is the [Apache Software License v2](https://www.apache.org/licenses/LICENSE-2.0)). 36 | 37 | Where we create independent code, we prefer to use the [GNU Affero General Public License 3](https://www.gnu.org/licenses/agpl-3.0.html), 38 | except for interface code which we would put under LGPL-3 (weak copyleft). 39 | Own documentation content is licensed under [Creative Commons BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/). 40 | 41 | Contributors sign-off that they adhere to these requirements by adding a `Signed-off-by` 42 | line to commit messages. 43 | 44 | ```bash 45 | My fancy commit message 46 | 47 | Signed-off-by: Christian Berendt 48 | ``` 49 | 50 | Git has a `-s` command line option to append this automatically to your commit message: 51 | 52 | ```bash 53 | git commit -s -m 'My fancy commit message' 54 | ``` 55 | 56 | The status of a pull request is set to failed if commits do not contain a valid `Signed-off-by` line. 57 | 58 | ![Failed DCO in GitHub](github-failed-dco.png) 59 | 60 | Considerations behind the choice of AGPLv3, CC-BY-SA and the usage of the DCO can be found [license-considerations.md](https://github.com/SovereignCloudStack/docs/blob/main/community/license-considerations.md). 61 | 62 | ## Further reading 63 | 64 | - [https://developercertificate.org/](https://developercertificate.org/) 65 | - [https://julien.ponge.org/blog/developer-certificate-of-origin-versus-contributor-license-agreements/](https://julien.ponge.org/blog/developer-certificate-of-origin-versus-contributor-license-agreements/) 66 | - [https://lwn.net/Articles/592503/](https://lwn.net/Articles/592503/) 67 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "version": "1.0.0", 4 | "description": "home and entry point for all documentation regarding scs", 5 | "license": "SEE LICENSE IN LICENSE.md", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/SovereignCloudStack/docs.git" 12 | }, 13 | "keywords": [ 14 | "documentation", 15 | "sovereigncloudstack" 16 | ], 17 | "bugs": { 18 | "url": "https://github.com/SovereignCloudStack/docs/issues" 19 | }, 20 | "homepage": "https://github.com/SovereignCloudStack/docs#readme", 21 | "scripts": { 22 | "docusaurus": "docusaurus", 23 | "start": "docusaurus start", 24 | "build": "docusaurus build", 25 | "swizzle": "docusaurus swizzle", 26 | "deploy": "docusaurus deploy", 27 | "clear": "docusaurus clear", 28 | "serve": "docusaurus serve", 29 | "write-translations": "docusaurus write-translations", 30 | "write-heading-ids": "docusaurus write-heading-ids", 31 | "typecheck": "tsc", 32 | "postinstall": "node getDocs.js && node populateStds.js && node populateCerts.js && node populateClouds.js", 33 | "test": "echo \"Error: no test specified\" && exit 1", 34 | "lint:md": "markdownlint-cli2 \"**/*.md\"", 35 | "fix:md": "markdownlint-cli2-fix \"**/*.md\"", 36 | "prepare": "husky install", 37 | "format": "prettier --log-level warn --write \"./**/*.{jsx,js}\"" 38 | }, 39 | "dependencies": { 40 | "@docusaurus/core": "^3.9.2", 41 | "@docusaurus/plugin-client-redirects": "^3.9.2", 42 | "@docusaurus/preset-classic": "^3.9.2", 43 | "@docusaurus/theme-mermaid": "^3.9.2", 44 | "@easyops-cn/docusaurus-search-local": "^0.45.0", 45 | "@fullcalendar/core": "^6.0.1", 46 | "@fullcalendar/daygrid": "^6.0.1", 47 | "@fullcalendar/icalendar": "^6.0.1", 48 | "@fullcalendar/interaction": "^6.0.1", 49 | "@fullcalendar/react": "^6.0.1", 50 | "@fullcalendar/timegrid": "^6.0.1", 51 | "@mdx-js/react": "^3.1.0", 52 | "clsx": "^1.2.1", 53 | "husky": "^8.0.3", 54 | "lint-staged": "^13.1.2", 55 | "markdownlint-cli2": "^0.7.1", 56 | "markdownlint-rule-search-replace": "^1.0.9", 57 | "node-fetch": "^2.7.0", 58 | "prism-react-renderer": "^2.3.1", 59 | "react": "^18.3.1", 60 | "react-dom": "^18.3.1", 61 | "yaml": "^2.6.1" 62 | }, 63 | "devDependencies": { 64 | "@docusaurus/eslint-plugin": "^3.6.3", 65 | "@docusaurus/module-type-aliases": "^3.6.3", 66 | "@docusaurus/tsconfig": "^3.6.3", 67 | "@docusaurus/types": "^3.6.3", 68 | "@types/react": "^18.3.12", 69 | "@typescript-eslint/eslint-plugin": "^5.43.0", 70 | "eslint": "^8.28.0", 71 | "eslint-config-love": "^71.0.0", 72 | "eslint-plugin-import": "^2.26.0", 73 | "eslint-plugin-markdownlint": "^0.4.0", 74 | "eslint-plugin-n": "^15.5.1", 75 | "eslint-plugin-promise": "^6.1.1", 76 | "eslint-plugin-react": "^7.31.11", 77 | "markdownlint": "^0.26.2", 78 | "markdownlint-cli": "^0.32.2", 79 | "markdownlint-rule-relative-links": "^2.1.0", 80 | "prettier": "3.0.3", 81 | "typescript": "~5.2.2" 82 | }, 83 | "browserslist": { 84 | "production": [ 85 | ">0.5%", 86 | "not dead", 87 | "not op_mini all" 88 | ], 89 | "development": [ 90 | "last 1 chrome version", 91 | "last 1 firefox version", 92 | "last 1 safari version" 93 | ] 94 | }, 95 | "engines": { 96 | "node": ">=20.0" 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /docs/03-container/index.md: -------------------------------------------------------------------------------- 1 | # Container Layer Introduction 2 | 3 | The container layer within the Sovereign Cloud Stack (SCS) offers a robust solution for managing container workloads on a Kubernetes infrastructure. It facilitates the on-demand creation and scaling of Kubernetes clusters, catering to various needs across development, testing, deployment, and operation of services and applications. While the container layer is versatile for a range of use cases, the most common ones include: 4 | 5 | - Self-Service: Here, entities can empower their development teams with the autonomy to spawn and manage their clusters on demand, fostering a more agile and responsive development environment. 6 | - KaaS (Kubernetes as a Service): In this model, an SCS Cloud provider can offer their customers a managed Kubernetes service, abstracting much of the underlying operational complexity from their customers. 7 | 8 | ## Target groups 9 | 10 | - DevOps/SysOps Teams: They are the primary beneficiaries as the container layer promotes flexible, on-demand operations helpful for continuous development, testing, deployment, and service management. 11 | - Cloud Service Providers: By delivering a standardized container orchestration platform, they can provide more reliable and robust services to their customers, enhancing their product portfolio. 12 | 13 | ## What is it not 14 | 15 | - The container layer is not an alternative to Infrastructure as a Service (IaaS) but rather an extension that allows for more streamlined operation and management of containerized applications. 16 | - Although the container layer doesn't directly support Serverless Containers or Functions as a Service, these can be run on a Kubernetes cluster. However, as of now, the SCS container layer doesn't offer specialized tools for these use cases. 17 | 18 | ### Prerequisites and Requirements 19 | 20 | - Knowledge: Familiarity with Kubernetes, container orchestration, and basic cloud infrastructure principles is pivotal. 21 | - Software: The core software component are the Cluster Stacks based on Cluster API, crafted to function best on OpenStack environments. Although designed to run on the SCS IaaS layer, with minor configuration adjustments, it can operate on any OpenStack environment. 22 | - Hardware: Virtualization-enabled hardware capable of running OpenStack is essential if hosting the IaaS layer independently. For further details, refer to the IaaS layer documentation. 23 | 24 | ### Features 25 | 26 | - Automated Cluster Management: The Cluster API automates the process of creating, scaling, managing and updating Kubernetes clusters, thus significantly reducing the operational overhead. 27 | - Standardized Operations: Upholding SCS standards across various clusters ensures operational consistency and reliability. 28 | - Integration with OpenStack: The Cluster Stacks are tailored to work seamlessly with SCS IaaS (OpenStack), thus offering a unified platform for managing both containers and the underlying infrastructure. 29 | - Container Registry Integration: The container layer has an optional container registry, facilitating easy management and deployment of container images. 30 | - Cluster Addons: Cluster Stacks come with a small default set of workload applications needed to make the cluster usable, such as CNI plugin, CSI plugin and a cloud controller manager. 31 | 32 | ### Limitations 33 | 34 | - Serverless/Functions as a Service Support: Lack of direct support for serverless containers and Functions as a Service (FaaS) might require additional tools or platforms. 35 | -------------------------------------------------------------------------------- /static/data/architecturalOverviewData.json: -------------------------------------------------------------------------------- 1 | { 2 | "ops": [ 3 | { 4 | "title": "Ops Layer", 5 | "body": "Tooling and infrastructure design for easy, efficient and transparent ways to operate an SCS Cloud.", 6 | "url": "/docs/category/operating-scs", 7 | "buttonText": "Learn More", 8 | "components": [ 9 | { 10 | "title": "Status Page", 11 | "url": "/docs/category/status-page", 12 | "mandatory": "true", 13 | "stable": "true" 14 | }, 15 | { 16 | "title": "Monitoring", 17 | "url": "/docs/category/monitoring", 18 | "mandatory": "false", 19 | "stable": "true" 20 | }, 21 | { 22 | "title": "SCS Health Monitor", 23 | "url": "/docs/operating-scs/components/scs-health-monitor/overview", 24 | "mandatory": "true", 25 | "stable": "true" 26 | }, 27 | { 28 | "title": "Central API", 29 | "url": "/docs/operating-scs/components/central-api/overview", 30 | "mandatory": "true", 31 | "stable": "true" 32 | }, 33 | { 34 | "title": "Automated Pentesting IaaS", 35 | "url": "/docs/operating-scs/components/automated-pentesting-iaas/overview", 36 | "mandatory": "true", 37 | "stable": "true" 38 | }, 39 | { 40 | "title": "Automated Pentesting KaaS", 41 | "url": "/docs/operating-scs/components/automated-pentesting-kaas/overview", 42 | "mandatory": "true", 43 | "stable": "true" 44 | } 45 | ] 46 | } 47 | ], 48 | "container": [ 49 | { 50 | "title": "Container Layer", 51 | "body": "SCS offers a robust solution for managing container workloads on a Kubernetes infrastructure.", 52 | "url": "/docs/container", 53 | "buttonText": "Learn More", 54 | "components": [ 55 | { 56 | "title": "KaaS V2: Cluster Stacks", 57 | "url": "/docs/category/cluster-stacks", 58 | "mandatory": "false", 59 | "stable": "true" 60 | }, 61 | { 62 | "title": "Container Registry", 63 | "url": "/docs/category/container-registry", 64 | "mandatory": "false", 65 | "stable": "true" 66 | } 67 | ] 68 | } 69 | ], 70 | "iaas": [ 71 | { 72 | "title": "IaaS Layer", 73 | "body": "SCS offers OpenStack infrastructure solutions based on KVM virtualization to deploy VM workloads and enabling the container layer optionally.", 74 | "url": "/docs/category/iaas-layer", 75 | "buttonText": "Learn More", 76 | "components": [ 77 | { 78 | "title": "Image Manager", 79 | "url": "/docs/iaas/components/image-manager", 80 | "mandatory": "true", 81 | "stable": "true" 82 | }, 83 | { 84 | "title": "Flavor Manager", 85 | "url": "/docs/iaas/components/flavor-manager", 86 | "mandatory": "true", 87 | "stable": "true" 88 | } 89 | ] 90 | } 91 | ], 92 | "iam": [ 93 | { 94 | "title": "IAM Layer", 95 | "body": "Working on Keycloak federated identity provider within our Team IAM.", 96 | "url": "/docs/iam", 97 | "buttonText": "Learn More", 98 | "components": [ 99 | { 100 | "title": "Keycloak", 101 | "url": "/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations", 102 | "mandatory": "false", 103 | "stable": "true" 104 | } 105 | ] 106 | } 107 | ] 108 | } 109 | -------------------------------------------------------------------------------- /community/contribute/adding-docs-guide.md: -------------------------------------------------------------------------------- 1 | # Adding Docs Guide 2 | 3 | In this Guide you will learn how to integrate your documentation to the SCS documentation, which you will find on [docs.scs.community](https://docs.scs.community). 4 | 5 | ## Step 1 – Documentation type 6 | 7 | Determine the type of your documentation and click to continue. 8 | 9 | 1. [Technical documentation](#1-technical-documentation) 10 | 2. [Operational documentation](#2-operational-documentation) 11 | 3. [Community documentation](#3-community-documentation) 12 | 13 | If unsure don't hestitate to ask us at [Matrix](https://github.com/SovereignCloudStack/docs/blob/main/community/communication/matrix.md) 14 | 15 | ## 1. Technical Documentation 16 | 17 | ### Step 1 – Checklist 18 | 19 | Your repository containing the documentation has to... 20 | 21 | - be a public repository 22 | - contain a directory named `/doc` or `/docs` within root, containing the documentation files 23 | 24 | The documentation files have to be in markdown format and... 25 | 26 | - comply [SCS licensing guidelines](https://github.com/SovereignCloudStack/docs/blob/main/community/license-considerations.md) 27 | - match our 28 | - [markdown file structure guideline](https://github.com/SovereignCloudStack/docs/blob/main/community/contribute/doc-files-structure-guide.md) 29 | - linting Rules 30 | - [styleguide](https://github.com/SovereignCloudStack/docs/blob/main/community/contribute/styleguide.md) 31 | 32 | ### Step 2 – Adding your repo to the docs.json 33 | 34 | File a Pull Request within the [docs](https://github.com/SovereignCloudStack/docs) repository and add your repo to the docs.package.json: 35 | 36 | ```json 37 | [ 38 | { 39 | "repo": "demo-organisation/demo-repository", 40 | "source": "doc/*.md", 41 | "target": "docs", 42 | "label": "demo-repository-label" 43 | } 44 | ] 45 | ``` 46 | 47 | | key | description | 48 | | ------ | ----------------------------------------------------------------------------------------------------------------- | 49 | | repo | reference to github organisation and repository | 50 | | source | path to content to copy: Either glob matching individual markdown files OR the path of a single directory | 51 | | target | directory where the files should be copied to within the docs-page repo | 52 | | label | label for directory. only mandatory if source file is set to copy only \*.md files and not the complete directory | 53 | 54 | Once it is approved and merged, a postinstall script will be triggered within the build process. This initiates downloading, copy and distilling which results in this static generated [documentation](https://docs.scs.community) page – now with your content. 55 | 56 | An explanation on how the sync & distill workflow and a guide on how to test it in a local development environment you will find [here](https://github.com/SovereignCloudStack/docs/blob/main/community/contribute/docs-workflow-explanation.md). 57 | 58 | ## 2. Operational documentation 59 | 60 | Your doc files contain operational knowledge. Which layer in the stack do they belong to? 61 | 62 | 1. iaas 63 | 2. iam 64 | 3. kaas 65 | 4. operations 66 | 67 | File a Pull Request within the [docs](https://github.com/SovereignCloudStack/docs) repository and add your markdown files to the fitting directory. 68 | 69 | ## 3. Community documentation 70 | 71 | Your doc files contain knowledge regarding our community? Choose the right directory. If unsure don't hestitate to ask us at [Matrix](https://github.com/SovereignCloudStack/docs/blob/main/community/communication/matrix.md). 72 | 73 | File a Pull Request within the `docs` repository and add your markdown files to the fitting directory. 74 | -------------------------------------------------------------------------------- /user-docs/usage-hints/find-image/find_img.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Find Image by properties 4 | # 5 | # (c) Kurt Garloff , 7/2025 6 | # SPDX-License-Identifier: MIT 7 | 8 | usage() 9 | { 10 | echo "Usage: find-img [-s] distro version [purpose]" 11 | echo "Returns all images matching, latest first, purpose defaults to generic" 12 | echo "If some images have the wanted purpose, only those will be shown" 13 | } 14 | 15 | get_images_raw() 16 | { 17 | # global OS_RESP 18 | DIST=$(echo "$1" | tr A-Z a-z) 19 | VERS="$2" 20 | #VERS=$(echo "$2" | tr A-Z a-z) 21 | shift; shift 22 | #echo "DEBUG: openstack image list --property os_distro=$DIST --property os_version=$VERS $@ -f value -c ID -c Name --sort created_at:desc" 23 | OS_RESP=$(openstack image list --property os_distro="$DIST" --property os_version="$VERS" $@ -f value -c ID -c Name --sort name:desc,created_at:desc) 24 | } 25 | 26 | 27 | img_sort_heuristic() 28 | { 29 | # Acts on global OS_RESP 30 | # FIXME: We could do all sorts of advanced heuristics here, looking at the name etc. 31 | # We only do a few pattern matches here 32 | # distro version purpose 33 | local NEW_RESP0=$(echo "$OS_RESP" | grep -i "^[0-9a-f\-]* $1 $2 $3\$") 34 | # distro version purpose with extras appended 35 | local NEW_RESP1=$(echo "$OS_RESP" | grep -i "^[0-9a-f\-]* $1 $2 $3" | grep -iv "^[0-9a-f\-]* $1 $2 $3\$") 36 | # distro purpose version 37 | local NEW_RESP2=$(echo "$OS_RESP" | grep -i "^[0-9a-f\-]* $1 $3 $2\$") 38 | # distro purpose version with extras appended 39 | local NEW_RESP3=$(echo "$OS_RESP" | grep -i "^[0-9a-f\-]* $1 $3 $2" | grep -iv "^[0-9a-f\-]* $1 $3 $2\$") 40 | # distro version 41 | local NEW_RESP4=$(echo "$OS_RESP" | grep -i "^[0-9a-f\-]* $1 $2\$") 42 | # distro version with extras (but not purpose) 43 | local NEW_RESP5=$(echo "$OS_RESP" | grep -i "^[0-9a-f\-]* $1 $2" | grep -iv "^[0-9a-f\-]* $1 $2\$" | grep -iv "^[0-9a-f\-]* $1 $2 $3") 44 | # distro extra version (but extra != purpose) 45 | local NEW_RESP6=$(echo "$OS_RESP" | grep -i "^[0-9a-f\-]* $1 .*$2\$" | grep -iv "^[0-9a-f\-]* $1 $3 $2\$" | grep -iv "$1 $2\$") 46 | OS_RESP=$(echo -e "$NEW_RESP0\n$NEW_RESP1\n$NEW_RESP2\n$NEW_RESP3\n$NEW_RESP4\n$NEW_RESP5\n$NEW_RESP6" | sed '/^$/d') 47 | } 48 | 49 | get_images() 50 | { 51 | PURPOSE="${3:-generic}" 52 | PURP="$PURPOSE" 53 | get_images_raw "$1" "$2" --property os_purpose=$PURPOSE 54 | if test -z "$OS_RESP"; then 55 | echo "WARN: No image found with os_distro=$1 os_version=$2 os_purpose=$PURPOSE" 1>&2 56 | PURP="" 57 | # We're screwed as we can not filter for the absence of os_purpose with CLI 58 | # We could loop and do an image show and then flter out, but that's very slow 59 | get_images_raw "$1" "$2" # --property os_purpose= 60 | # FIXME: We need to filter out images with os_purpose property set 61 | NEW_RESP="" 62 | while read ID Name; do 63 | PROPS=$(openstack image show $ID -f value -c properties) 64 | if test $? != 0; then continue; fi 65 | if echo "$PROPS" | grep os_purpose >/dev/null 2>&1; then continue; fi 66 | NEW_RESP=$(echo -en "$NEW_RESP\n$ID $Name") 67 | done < <(echo "$OS_RESP") 68 | OS_RESP=$(echo "$NEW_RESP" | sed '/^$/d') 69 | fi 70 | NR_IMG=$(echo "$OS_RESP" | sed '/^$/d' | wc -l) 71 | if test "$NR_IMG" = "0"; then echo "ERROR: No image found with os_distro=$1 os_version=$2" 1>&2; return 1 72 | elif test "$NR_IMG" = "1"; then return 0 73 | else 74 | echo "DEBUG: Several $PURP images matching os_distro=$1 os_version=$2" 1>&2; 75 | if test -n "$STRICT"; then return 1; fi 76 | img_sort_heuristic "$1" "$2" "$PURPOSE" 77 | return 0 78 | fi 79 | } 80 | 81 | if test -z "$OS_CLOUD" -a -z "$OS_AUTH_URL"; then 82 | echo "You need to configure clouds.yaml/secure.yaml and set OS_CLOUD" 1>&2 83 | exit 2 84 | fi 85 | if test "$1" = "-s"; then STRICT=1; shift; fi 86 | if test -z "$1"; then usage; exit 1; fi 87 | 88 | get_images "$@" 89 | RC=$? 90 | echo "$OS_RESP" 91 | (exit $RC) 92 | -------------------------------------------------------------------------------- /src/plugins/docusaurus-plugin-matomo-analytics/index.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | // based on https://github.com/karser/docusaurus-plugin-matomo with extended parameters 4 | 5 | function matomoAnalytics(context, options) { 6 | const { siteConfig } = context 7 | const { themeConfig } = siteConfig 8 | const { matomoAnalytics } = themeConfig || {} 9 | 10 | if (!matomoAnalytics) { 11 | throw new Error( 12 | "Please specify 'matomo' object in 'themeConfig' with 'matomoUrl' and 'siteId' fields in it to use docusaurus-plugin-matomo" 13 | ) 14 | } 15 | 16 | const { matomoUrl, siteId } = matomoAnalytics 17 | 18 | if (!matomoUrl) { 19 | throw new Error( 20 | 'Please specify the `matomoUrl` field in the `themeConfig.matomo`' 21 | ) 22 | } 23 | if (!siteId) { 24 | throw new Error( 25 | 'Please specify the `siteId` field in the `themeConfig.matomo`' 26 | ) 27 | } 28 | 29 | const isProd = process.env.NODE_ENV === 'production' 30 | return { 31 | name: 'docusaurus-plugin-matomo-analytics', 32 | 33 | getClientModules() { 34 | return isProd ? [path.resolve(__dirname, './track')] : [] 35 | }, 36 | 37 | injectHtmlTags() { 38 | return { 39 | headTags: [ 40 | { 41 | tagName: 'link', 42 | attributes: { 43 | rel: 'preconnect', 44 | href: `${matomoAnalytics.matomoUrl}` 45 | } 46 | }, 47 | { 48 | tagName: 'script', 49 | innerHTML: ` 50 | var _paq = window._paq = window._paq || []; 51 | _paq.push(["setDocumentTitle", document.domain + "/" + document.title]); 52 | ${ 53 | matomoAnalytics.cookieDomain 54 | ? `_paq.push(["setCookieDomain", "${matomoAnalytics.cookieDomain}"]);` 55 | : '' 56 | } 57 | ${ 58 | matomoAnalytics.domains 59 | ? `_paq.push(["setDomains", ["${matomoAnalytics.domains}"]])` 60 | : '' 61 | } 62 | ${ 63 | matomoAnalytics.campaignNameKey 64 | ? `_paq.push(["setCampaignNameKey", "${matomoAnalytics.campaignNameKey}"]);` 65 | : '' 66 | } 67 | ${ 68 | matomoAnalytics.campaignKeywordKey 69 | ? `_paq.push(["setCampaignKeywordKey", "${matomoAnalytics.campaignKeywordKey}"]);` 70 | : '' 71 | } 72 | ${ 73 | matomoAnalytics.doNotTrack 74 | ? `_paq.push(["setDoNotTrack", ${matomoAnalytics.doNotTrack}]);` 75 | : '' 76 | } 77 | ${ 78 | matomoAnalytics.disableCookies 79 | ? '_paq.push(["disableCookies"]);' 80 | : '' 81 | } 82 | _paq.push(['trackPageView']); 83 | _paq.push(['enableLinkTracking']); 84 | (function() { 85 | var u="${matomoAnalytics.matomoUrl}"; 86 | _paq.push(['setTrackerUrl', u+'${ 87 | matomoAnalytics.phpLoader 88 | }']); 89 | _paq.push(['setSiteId', '${matomoAnalytics.siteId}']); 90 | var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; 91 | g.async=true; g.src=u+'${ 92 | matomoAnalytics.jsLoader 93 | }'; s.parentNode.insertBefore(g,s); 94 | })(); 95 | 96 | ` 97 | } 98 | ] 99 | } 100 | } 101 | } 102 | } 103 | 104 | module.exports = matomoAnalytics 105 | -------------------------------------------------------------------------------- /src/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react' 2 | import clsx from 'clsx' 3 | import Link from '@docusaurus/Link' 4 | import useDocusaurusContext from '@docusaurus/useDocusaurusContext' 5 | import Layout from '@theme/Layout' 6 | import styles from './index.module.css' 7 | import ContentCard from '../components/ContentCard' 8 | import ArchitecturalModel, { 9 | ArchitecturalLayerData 10 | } from '../components/ArchitecturalModel' 11 | 12 | function HomepageHeader() { 13 | const { siteConfig } = useDocusaurusContext() 14 | return ( 15 |
16 |
17 |

{siteConfig.title}

18 |

{siteConfig.tagline}

19 |
20 | 21 | Get Started 22 | 23 |
24 |
25 |
26 | ) 27 | } 28 | 29 | interface FeatureContent { 30 | title: string 31 | body: string 32 | buttonText: string 33 | url: string 34 | } 35 | 36 | export interface GlobalDataPlugin { 37 | default: { 38 | architecturalOverviewData: ArchitecturalLayerData 39 | featureContentData: any 40 | additionalResourcesData: any 41 | } 42 | } 43 | 44 | export interface GlobalData { 45 | 'global-data-plugin': GlobalDataPlugin 46 | } 47 | 48 | export default function Home(): JSX.Element { 49 | const context = useDocusaurusContext() 50 | const globalData = context.globalData as unknown as GlobalData 51 | 52 | const featureContent = globalData['global-data-plugin'].default 53 | .featureContentData as FeatureContent[] 54 | const additionalResources = globalData['global-data-plugin'].default 55 | .additionalResourcesData as FeatureContent[] 56 | 57 | return ( 58 | 59 |
60 |
61 |
62 |
63 |

Welcome to the SCS Documentation

64 |

65 | Find user guides, code samples, deployment examples, reference, 66 | community pages and more. 67 |

68 |
69 |
70 |
71 | {featureContent.map((card, index) => ( 72 |
73 | 79 |
80 | ))} 81 |
82 |
83 |
84 |

Architectural Layers

85 |
86 |
87 | 88 |
89 |
90 |
91 |
92 |

Additional Resources

93 |
94 |
95 |
96 | {additionalResources.map((card, index) => ( 97 |
98 | 104 |
105 | ))} 106 |
107 |
108 |
109 |
110 | ) 111 | } 112 | -------------------------------------------------------------------------------- /community/cloud-resources/getting-started-openstack.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Getting Started with OpenStack 3 | version: 2023-08-04 4 | author: Ralf Heiringhoff, Eduard Itrich, Mathias Fechner 5 | --- 6 | 7 | ## Getting Started with OpenStack CLI 8 | 9 | ## OpenStackClient (CLI) 10 | 11 | The OpenStackClient is installable via all major Linux Distributions: 12 | 13 | for debian and ubuntu with apt: 14 | 15 | ```bash 16 | sudo apt install python3-openstackclient 17 | ``` 18 | 19 | for ubuntu with snap openstack CLI is installable too: 20 | 21 | ```bash 22 | sudo snap install openstackclients 23 | ``` 24 | 25 | > [!NOTE] 26 | > Versions from Linux repository could be in a stable but old state. 27 | 28 | Install it directly via [pypi](https://pypi.org/project/python-openstackclient) 29 | from upstream is the recommend way. 30 | 31 | Here for example RHEL: 32 | 33 | ```bash 34 | sudo dnf install python3 python3-devel gcc python3-pip 35 | ``` 36 | 37 | Here for example Debian and Ubuntu: 38 | 39 | ```bash 40 | sudo apt install python3-minimal python3-pip python3-venv python3-dev build-essential 41 | ``` 42 | 43 | Here as example for SUSE 44 | 45 | ```bash 46 | sudo zypper in python3-pip python3-venv python3-dev 47 | ``` 48 | 49 | Here for example with Apple's MacOS 50 | 51 | ```bash 52 | brew install python3 53 | ``` 54 | 55 | > [!NOTE] 56 | > Python installation for windows systems please use the [python installation guide](https://www.python.org/downloads/windows/) 57 | > or recommend use the [Linux Subsystem WSL](https://learn.microsoft.com/de-de/windows/wsl/install) 58 | 59 | Python Virtualenv 60 | 61 | It is also recommended to use virtual environments, here as an example for 62 | Linux and MacOS: 63 | 64 | ```bash 65 | python3 -m venv oscli 66 | source oscli/bin/activate 67 | pip install --upgrade pip 68 | pip install python-openstackclient \ 69 | python-cinderclient \ 70 | python-designateclient \ 71 | python-glanceclient \ 72 | python-neutronclient \ 73 | python-novaclient \ 74 | python-octaviaclient \ 75 | python-barbicanclient 76 | 77 | ``` 78 | 79 | For further Information see the OpenStack Project upstream website 80 | [python-openstackclient](https://docs.openstack.org/python-openstackclient/latest/index.html). 81 | 82 | This repo holds examples for [clouds-public.yaml](clouds-public.yaml) + [clouds.yaml](clouds.yaml.sample). 83 | 84 | Alternatively you can download an OpenRC Environment file when you're logged 85 | in to Horizon: 86 | 87 | - upper right side :arrow_right: `` 88 | - OpenStack RC File 89 | 90 | ```bash 91 | $ source ./<$yourfile>-openrc.sh 92 | Please enter your OpenStack Password for project XXX as user YYY: 93 | ``` 94 | 95 | ```bash 96 | openstack --help 97 | ``` 98 | 99 | when you're using clouds.yaml you can specify multiple endpoints and 100 | select the specific endpoint by passing `--os-cloud=` to the 101 | openstack cmdline or setting `OS_CLOUD`. 102 | 103 | ```bash 104 | openstack --os-cloud MYCLOUD 105 | ``` 106 | 107 | or 108 | 109 | ```bash 110 | export OS_CLOUD=MYCLOUD 111 | openstack 112 | ``` 113 | 114 | OpenStack Client in action inside of the OSISM testbed: 115 | ![Example OpenStackClient in testbed](getting_started_openstack_anim.gif) 116 | 117 | ## Object Storage (S3) 118 | 119 | Create AWS like credentials with `openstack ec2 credentials create`. 120 | If you use libs3, store the access field in `S3_ACCESS_KEY_ID` and the secret 121 | field in`S3_SECRET_ACCESS_KEY` and set `S3_HOSTNAME=`. 122 | You will see the same buckets (containers) and objects whether you access your 123 | object store via the swift or via the s3 protocol. 124 | 125 | ## References 126 | 127 | - [OpenStack](https://www.openstack.org 'OpenStack Site') 128 | - [SovereignCloudStack](https://github.com/SovereignCloudStack 'SovereignCloudStack on github') 129 | - [OSISM](https://github.com/osism 'OSISM on github') 130 | - [ansible](https://docs.ansible.com/ansible/latest/collections/openstack/cloud/index.html 'Ansible Module OpenStack') 131 | - [terraform](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs 'OpenStack Terraform Provider') 132 | - [cloud-init](https://cloudinit.readthedocs.io/en/latest/ 'cloud-init documentation') 133 | -------------------------------------------------------------------------------- /src/components/ArchitecturalModel.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react' 2 | import ContentCard from './ContentCard' 3 | import styles from './architecturalmodel.module.css' 4 | import useDocusaurusContext from '@docusaurus/useDocusaurusContext' 5 | import { GlobalData } from '../pages' 6 | 7 | interface ArchitecturalLayerItem { 8 | title: string 9 | body: string 10 | url: string 11 | buttonText: string 12 | components?: [] 13 | } 14 | 15 | export interface ArchitecturalLayerData { 16 | ops: ArchitecturalLayerItem[] 17 | container: ArchitecturalLayerItem[] 18 | iaas: ArchitecturalLayerItem[] 19 | iam: ArchitecturalLayerItem[] 20 | } 21 | 22 | interface ArchitecturalModelProps { 23 | topLayers?: boolean 24 | } 25 | 26 | const ArchitecturalModel: React.FunctionComponent = ( 27 | props 28 | ) => { 29 | const { topLayers } = props 30 | const context = useDocusaurusContext() 31 | const globalData = context.globalData as unknown as GlobalData 32 | const data = 33 | globalData['global-data-plugin'].default.architecturalOverviewData 34 | 35 | if (!data) { 36 | return
No data available.
37 | } 38 | 39 | return ( 40 |
41 | {!topLayers && ( 42 |
47 |
SCS Component Map
48 |
49 | )} 50 |
51 |
54 | {data.ops.map((layer, index) => ( 55 | 65 | ))} 66 |
67 |
70 | {data.container.map((layer, index) => ( 71 |
76 | 85 |
86 | ))} 87 | {data.iaas.map((layer, index) => ( 88 |
89 | 98 |
99 | ))} 100 |
101 |
104 | {data.iam.map((layer, index) => ( 105 | 115 | ))} 116 |
117 |
118 |
119 | ) 120 | } 121 | 122 | export default ArchitecturalModel 123 | -------------------------------------------------------------------------------- /docs/08-faq/index.mdx: -------------------------------------------------------------------------------- 1 | # Frequently Asked Questions 2 | 3 | ## What does SCS stand for? 4 | 5 | The Sovereign Cloud Stack (SCS) provides standards for a range of cloud infrastructure types. It strives for interoperable and sovereign cloud offerings which can be deployed and used by a wide range of organizations and individuals. 6 | 7 | ## Who is SCS intended for? 8 | 9 | SCS is a Software Stack to power data centers of different scale. It empowers public or private cloud service providers to offer resources to their endusers. 10 | 11 | ## Who or what is behind SCS? 12 | 13 | SCS is run by the SCS Project Team which is based at the Open Source Business Alliance e.V. and 100% funded by the German Ministry of Economics and Climate Action (BMWK). Public money means public code. 14 | 15 | ## Why is there a need for a standardized cloud environment? 16 | 17 | A standardized environment promotes interoperability, reduces vendor lock-in, and facilitates smoother transitions between providers. It gives individuals, companies and public institutions the freedom of choice. 18 | 19 | ## Where can I find the SCS standards? 20 | 21 | The SCS standards are available on the standards pages within our documentation page. [Find them here](https://docs.scs.community/standards) 22 | 23 | ## How is the SCS different from other cloud environments (e.g. AWS, Azure,...)? 24 | 25 | Unlike proprietary clouds, SCS emphasizes standardization, ensuring interoperability and reduced dependency on one provider. 26 | 27 | ## My company already has a cloud environment. Can we still use the SCS? 28 | 29 | Yes, SCS can complement existing environments, enhancing standardization and interoperability. 30 | 31 | ## What does reference implementation mean? 32 | 33 | Reference implementation is a concrete example or blueprint of how the SCS standards can be implemented. 34 | 35 | ## Do I need to use the reference implementation to be SCS compliant? 36 | 37 | No, while the reference implementation is a guide, compliance requires adhering to SCS standards, not the exact blueprint of the reference implementation. [Check the standards page on how to be SCS-compatible](https://docs.scs.community/standards/) 38 | 39 | ## Do I have to use all layers of the reference implementation (IaaS, CaaS)? 40 | 41 | No, you can choose layers based on your needs and still be SCS compliant. 42 | 43 | ## What does IaaS mean? 44 | 45 | IaaS stands for Infrastructure as a Service, providing virtualized computing resources over the internet. 46 | 47 | ## How is the IaaS layer structured? 48 | 49 | IaaS typically comprises virtual machines, storage, and network resources, all offered as scalable services. [Find the architecture here](https://docs.scs.community/docs/category/iaas-layer) 50 | 51 | ## What does CaaS mean? (Container Layer) 52 | 53 | CaaS refers to Container as a Service, where providers offer container orchestration platforms. 54 | 55 | ## I want to try out the SCS! Where do I start? 56 | 57 | **As a user**: 58 | 59 | - Existing SCS Clouds: Explore and test on any of the cloud providers offering SCS. [Choose one from here](https://docs.scs.community/standards/certification/overview#compliant-cloud-environments) 60 | 61 | **As a Cloud Service Provider**: 62 | 63 | - **Cloud in a Box**: Start with our pre-packaged solutions. [Link to Ciab](https://docs.scs.community/docs/iaas/deployment-examples/cloud-in-a-box/advanced-guides/cloud-in-a-box) 64 | - **Testbed**: Use the SCS test environment to experiment. [Link to Testbed/deployment example](https://docs.scs.community/docs/iaas/deployment-examples/cloud-in-a-box/advanced-guides/testbed) 65 | 66 | ## I want to use an SCS Cloud! How do I get started? 67 | 68 | **As a user**: 69 | 70 | - Browse our [list of providers](https://docs.scs.community/standards/certification/overview#compliant-cloud-environments) and choose one that fits your needs. 71 | 72 | **As a Cloud Service Provider**: 73 | 74 | - Adopt SCS standards and utilize our [resources and tools](https://docs.scs.community/docs/category/components) to integrate them. 75 | 76 | ## I want to use the SCS in my company and build my own cloud! Where do I start? 77 | 78 | Start by understanding SCS standards and then move on to the reference implementation. [Link to guide](https://docs.scs.community/standards/). 79 | 80 | ## I have a technical problem. Where can I find help? 81 | 82 | Refer to our support section or check our community channels for assistance. [Link to community](https://docs.scs.community/community). 83 | -------------------------------------------------------------------------------- /docs/05-iam/index.md: -------------------------------------------------------------------------------- 1 | # Introduction on Identity Management and Federation in SCS 2 | 3 | Sovereign Cloud Stack wants to make it possible for operators to delegate 4 | administration of user identities to the organizational entities that the 5 | users are part of. Usually that's customer organizations but it could also 6 | be the operator itself. Federation protocols like OpenID Connect can be used 7 | to achieve that goal. To simplify connecting the different parts of SCS 8 | to customer owned IAM solutions, the SCS reference implementation offers 9 | Keycloak as central Identity Provider (IdP) service. 10 | 11 | ## Deployment 12 | 13 | Keycloak can be deployed by running 14 | 15 | ``` 16 | osism apply keycloak 17 | ``` 18 | 19 | The required Keycloak client configuration that allows Keystone to obtain 20 | OIDC token from Keycloak needs to be deployed by running 21 | 22 | ``` 23 | osism apply keycloak-oidc-client-config 24 | ``` 25 | 26 | After these steps Keystone should be able to obtain token using the 27 | Device Authorization Grant with PKCE, which is configured by default in the 28 | `wsgi-keystone.conf` deployed in SCS. 29 | 30 | ## Accessing Keycloak 31 | 32 | Currently deployed on the manager node, by default under `https://keycloak.`. 33 | Details TODO. 34 | 35 | ## Identity Mapping 36 | 37 | The idea is that customer can create groups with specific names in their own IAM. 38 | These shall be mapped to a claim `groups` to be included in the OIDC token. 39 | Via the Keystone [mapping](https://docs.openstack.org/keystone/latest/admin/federation/mapping_combinations.html) 40 | they shall be mapped to roles on OpenStack projects. 41 | [The corresponding section for Developers](https://docs.scs.community/contributor-docs/operations/iam/identity-federation-in-scs) may be interesting for more technical details. 42 | Please be aware that currently there are still some technical challenges to be solved 43 | within the OpenStack Keystone mapping engine and the mapping rules to make this work 44 | seamlessly. 45 | 46 | ## SCS to SCS federation 47 | 48 | Federation between separate deployments of SCS is possible via the IdP by 49 | means of OpenID Connect. 50 | The section on [inter SCS federation setup](https://docs.scs.community/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations) explains the required steps in some detail. 51 | 52 | ### Prerequisites and Requirements 53 | 54 | - Knowledge: Familiarity with Keycloak, OIDC federation, and basic SSL and web security principles is pivotal. 55 | - Software: The core software component is the OpenID-Connect identity provider, configured to function optimally with OpenStack environments. While the SCS reference implementation focusses on Keycloak as IdP, with appropriate configuration adjustments any OAuth 2.0 compliant IdP should be suitable as an alternative. Each implemntation may have its own pros and cons. 56 | 57 | ### Features 58 | 59 | - Horizon Web SSO 60 | - OpenStack CLI use via the Device Authorization Grant 61 | 62 | ### Limitations 63 | 64 | - Keystone currently still has limitations in its mapping engine, which are addressed by the SCS development team as we 65 | see possibilities and alignement with upstream OpenDev development plans. Automatically creating `ephemeral` users in 66 | their specific OpenStack domains, as specified in their OIDC token is one example, currently beeing worked on. Please 67 | check carefully if the technical results meet the security demands of your specific environment. 68 | - Keystone currently has another limitation which is being addressed by the SCS development team aligned 69 | with upstream OpenDev development plans: The roles for federated users are stored on the database for the `ephemeral` users 70 | created during a federated login. This limits the ability to modify users roles from the identity source directly, as roles of 71 | the `epehemeral` users do not get cleaned up or updated based on changes in the claims contained in the OpenID-Connect token. 72 | 73 | ### Current state and future Outlook 74 | 75 | Currently SCS exemplifies deploying Keycloak on the management plane. This shall be moved to a Kubernetes based 76 | management plane to improve scalability and architecture. 77 | 78 | In the near future, the Container layer shall be able to make use of the IdP to allow federated users to access Kubernetes. 79 | In the mid term, workloads on Kubernetes shall be able to make use of OAuth tokens to access resources on the IaaS layer. 80 | -------------------------------------------------------------------------------- /docs.package.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "repo": "SovereignCloudStack/release-notes", 4 | "source": "*.md", 5 | "target": "docs", 6 | "label": "06-releases" 7 | }, 8 | { 9 | "repo": "osism/osism.github.io", 10 | "source": "docs/guides/operations-guide/openstack/tools/*", 11 | "target": "docs/02-iaas/components", 12 | "label": "" 13 | }, 14 | { 15 | "repo": "SovereignCloudStack/standards", 16 | "source": ["Standards/*.md", "Tests/scs-*.yaml"], 17 | "target": "standards", 18 | "label": "" 19 | }, 20 | { 21 | "repo": "osism/osism.github.io", 22 | "source": "docs/guides", 23 | "target": "docs/02-iaas/", 24 | "label": "" 25 | }, 26 | { 27 | "repo": "osism/osism.github.io", 28 | "source": "docs/cloud-in-a-box", 29 | "target": "docs/02-iaas/deployment-examples", 30 | "label": "" 31 | }, 32 | { 33 | "repo": "osism/osism.github.io", 34 | "source": "docs/testbed", 35 | "target": "docs/02-iaas/deployment-examples", 36 | "label": "" 37 | }, 38 | { 39 | "repo": "SovereignCloudStack/k8s-harbor", 40 | "source": "docs", 41 | "target": "docs/03-container/components", 42 | "label": "container-registry" 43 | }, 44 | { 45 | "repo": "SovereignCloudStack/status-page-openapi", 46 | "source": "docs", 47 | "target": "docs/04-operating-scs/components", 48 | "label": "status-page-openapi" 49 | }, 50 | { 51 | "repo": "SovereignCloudStack/status-page-api", 52 | "source": "docs", 53 | "target": "docs/04-operating-scs/components", 54 | "label": "status-page-api" 55 | }, 56 | { 57 | "repo": "SovereignCloudStack/status-page-deployment", 58 | "source": "docs", 59 | "target": "docs/04-operating-scs/components", 60 | "label": "status-page-deployment" 61 | }, 62 | { 63 | "repo": "SovereignCloudStack/status-page-web", 64 | "source": "docs", 65 | "target": "docs/04-operating-scs/components", 66 | "label": "status-page-web" 67 | }, 68 | { 69 | "repo": "SovereignCloudStack/k8s-observability", 70 | "source": "docs", 71 | "target": "docs/04-operating-scs/components", 72 | "label": "monitoring" 73 | }, 74 | { 75 | "repo": "SovereignCloudStack/openstack-health-monitor", 76 | "source": "docs/*.md", 77 | "target": "docs/04-operating-scs/01-guides", 78 | "label": "openstack-health-monitor" 79 | }, 80 | { 81 | "repo": "SovereignCloudStack/scs-health-monitor", 82 | "source": [ 83 | "docs/overview.md", 84 | "docs/Workflow.md", 85 | "docs/Testflow.md", 86 | "docs/ObservabilityStack/SetupObservabilityStack.md" 87 | ], 88 | "target": "docs/04-operating-scs/components", 89 | "label": "scs-health-monitor" 90 | }, 91 | { 92 | "repo": "SovereignCloudStack/central-api", 93 | "source": "docs/*.md", 94 | "target": "docs/04-operating-scs/components", 95 | "label": "central-api" 96 | }, 97 | { 98 | "repo": "SovereignCloudStack/security-infra-scan-pipeline", 99 | "source": "docs/*.md", 100 | "target": "docs/04-operating-scs/components", 101 | "label": "automated-pentesting-iaas" 102 | }, 103 | { 104 | "repo": "SovereignCloudStack/security-infra-scan-pipeline", 105 | "source": "docs/images/*.png", 106 | "target": "docs/04-operating-scs/components", 107 | "label": "automated-pentesting-iaas/images" 108 | }, 109 | { 110 | "repo": "SovereignCloudStack/security-k8s-scan-pipeline", 111 | "source": "docs/*.md", 112 | "target": "docs/04-operating-scs/components", 113 | "label": "automated-pentesting-kaas" 114 | }, 115 | { 116 | "repo": "SovereignCloudStack/csctl", 117 | "source": "docs/*.md", 118 | "target": "docs/03-container/components/cluster-stacks/components", 119 | "label": "csctl" 120 | }, 121 | { 122 | "repo": "SovereignCloudStack/cluster-stacks", 123 | "source": "docs/*", 124 | "target": "docs/03-container/components/cluster-stacks/components", 125 | "label": "cluster-stacks" 126 | }, 127 | { 128 | "repo": "SovereignCloudStack/cluster-stack-operator", 129 | "source": ["docs/*"], 130 | "target": "docs/03-container/components/cluster-stacks/components", 131 | "label": "cluster-stack-operator" 132 | }, 133 | { 134 | "repo": "SovereignCloudStack/hardware-landscape", 135 | "source": ["documentation/overview.md"], 136 | "target": "docs/turnkey-solution", 137 | "label": "" 138 | }, 139 | { 140 | "repo": "SovereignCloudStack/opendesk-on-scs", 141 | "source": "docs/*", 142 | "target": "user-docs/application-examples", 143 | "label": "opendesk-on-scs" 144 | } 145 | ] 146 | -------------------------------------------------------------------------------- /docs/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Introduction 3 | sidebar_position: 1 4 | --- 5 | 6 | import ArchitecturalModel from '../src/components/ArchitecturalModel' 7 | 8 | ## About 9 | 10 | The Sovereign Cloud Stack combines the best of Cloud Computing in one unified standard. 11 | SCS is built, backed, and operated by an active open-source community worldwide. 12 | 13 | ## Architectural Overview 14 | 15 | 16 | 17 | ## Use Cases and Deployment Examples 18 | 19 | ### Virtualization (IaaS) Layer 20 | 21 | The SCS IaaS Reference Implementation is based on [OSISM](https://osism.tech/). 22 | 23 | #### Quick Start with Cloud-in-a-Box 24 | 25 | You can do a single node installation for learning, testing or development purposes. 26 | The Cloud-in-a-Box configuration was built explicitly for this scenario. 27 | Check it out [here](/docs/iaas/deployment-examples/cloud-in-a-box) 28 | It comes with a complete set of services, even Ceph is part of it 29 | (despite of course not offering much redundancy on a single-node). 30 | 31 | #### Reference Implementation Testbed 32 | 33 | The fastest way to get in touch with SCS is to deploy a SCS cloud virtually. 34 | 35 | This means that you set up an SCS test installation including all the infrastructure 36 | pieces such as database, message queueing, ceph, monitoring and logging, IAM, the 37 | [OpenStack](https://openstack.org/) core services, and (soon) the Container layer 38 | on top of an existing OpenStack IaaS platform, ideally one that allows for nested 39 | virtualization. 40 | 41 | Read the [testbed docs](/docs/iaas/deployment-examples/testbed) to learn how to get the 42 | testbed running. Please read carefully through the 43 | [deployment](/docs/iaas/deployment-examples/testbed#deployment) section of the 44 | manual. 45 | 46 | #### Examples for real deployments 47 | 48 | [artcodix](https://artcodix.com/) has [shared](/docs/iaas/deployment-examples/artcodix/) 49 | some details on their production setup. The SCS team itself has created [extensive 50 | documentation](/docs/turnkey-solution/hardware-landscape/) including details on the 51 | used hardware. 52 | 53 | ### Container Layer 54 | 55 | The Reference Implementation (v2) for the container (Kubernetes-as-a-Service = KaaS) layer 56 | is provided by [Cluster Stacks](/docs/category/cluster-stacks) 57 | from [syself](https://syself.com/). 58 | 59 | #### Cluster Stacks 60 | 61 | With the Cluster Stacks, in the V2 KaaS reference implementation, we provide an opinionated optimized configuration of Kubernetes cluster management based on [Kubernetes Cluster-API](https://cluster-api.sigs.k8s.io/). 62 | Through better packaging, integrated testing, and bundled configuration, SCS-based Kubernetes clusters provide easier individualization. 63 | Throughout the R6 development cycle Cluster Stacks were taken from a technical preview to be [functional and available on top of the IaaS reference implementation](https://github.com/SovereignCloudStack/issues/milestone/8) as well to replace the V1 KaaS reference implementation [k8s-cluster-api-provider](https://github.com/SovereignCloudStack/k8s-cluster-api-provider/). 64 | The Cluster Stacks have fully replaced V1 meanwhile to be the production-grade KaaS solution in SCS, please check out the 65 | [Quick Start Guide](/docs/container/components/cluster-stacks/providers/openstack/quickstart). 66 | For demo, test and development purposes, you can also try the [demo](https://github.com/SovereignCloudStack/cluster-stacks-demo) repository which is an implementation using the (not-for-production) Docker provider. Implementations for other infrastructure are intended; the one for Hetzner for example is maintained by syself itself. 67 | 68 | ### Public SCS Clouds in production 69 | 70 | Find the current list of scs compatible clouds [here](https://docs.scs.community/standards/certification/overview#compliant-cloud-environments). 71 | 72 | ### Development of SCS 73 | 74 | While the SCS project tracks the efforts across the released epics and user stories, the work on the code, whenever possible, happens upstream. As such, these repositories are usually not found in the SCS GitHub organization. SCS works directly in the following upstream projects: 75 | 76 | - CNCF projects, 77 | - OpenStack, 78 | - kolla-ansible, 79 | - OSISM and others. 80 | 81 | All code not pushed upstream can be found in the [SCS Github organization](https://github.com/SovereignCloudStack). 82 | 83 | ### Issues and Bugs 84 | 85 | If you can identify the affected component, raise the issue against the relevant repository in the SovereignCloudStack or OSISM space. Otherwise, you can use the [issues repository](https://github.com/SovereignCloudStack/issues). We appreciate PRs as well as issues; please don't forget to sign off your contributions see [contributor guide](https://docs.scs.community/community). 86 | 87 | ### Contribute and Connect 88 | 89 | Please see the [SCS contributor guide](https://docs.scs.community/community). 90 | 91 | ### Releases and Roadmap 92 | 93 | See our Release Notes [here](https://docs.scs.community/docs/category/releases) 94 | 95 | ## Standards, Conformity and Certification 96 | 97 | How to get compliant? What do I need to be compliant? What are the benefits? What does it involve? What to expect in the future? Learn more in the [standards section](https://docs.scs.community/standards). 98 | -------------------------------------------------------------------------------- /contributor-docs/operations/iam/openstack-federation-via-oidc.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: OpenStack Federation via OpenID-Connect 3 | type: 4 | status: Draft 5 | track: Global 6 | --- 7 | 8 | Keystone supports federating authentication and authorization decisions via several mechanisms 9 | as [documented by the project](https://docs.openstack.org/keystone/latest/admin/federation/introduction.html). 10 | 11 | In SCS OpenID Connect is used for federation between Keystone and the IdP, which is 12 | [currently provided by Keycloak](https://docs.scs.community/standards/scs-0300-v1-requirements-for-sso-identity-federation) 13 | in SCS. 14 | 15 | The following sections describe the setup. 16 | 17 | ## 1. Keystone 18 | 19 | [Keystone supports federated identities](https://docs.openstack.org/keystone/latest/admin/federation/federated_identity.html). 20 | To allow SCS to consume identities managed in external IAM solutions, 21 | federation protocols like OpenID Connect or SAML can be used. 22 | Keystone currently makes use of third party apache modules like 23 | [mod_auth_openidc](https://github.com/OpenIDC/mod_auth_openidc), 24 | [mod_oauth2](https://github.com/OpenIDC/mod_oauth2) and 25 | [mod_auth_mellon](https://github.com/UNINETT/mod_auth_mellon) to delegate 26 | authentication to a SSO IdP (i.e. SAML IdP or OpenID Connect provider). 27 | 28 | In OpenStack the apache modules are configured using the 29 | [wsgi-keystone.conf template](https://github.com/openstack/kolla-ansible/tree/master/ansible/roles/keystone/templates). 30 | 31 | In SCS we make use of the OAuth 2.0 Authorization Code Grant flow between Keystone and Keycloak 32 | and use PKCE (RFC 7636) with the S256 challenge method. 33 | 34 | In addition to the usual SSL CA of the environment, Keycloak uses separate certificates to sign the OIDC tokens. 35 | 36 | Due to the way the Keystone container image runs apache (in the foreground) and keystone itself (as WSGI module), 37 | reconfiguring the apache URL locations on the fly is not possible currently without a downtime of several seconds. 38 | That is the reason why SCS currently makes use of a single central proxy realm in Keycloak, to which Keystone 39 | connects. 40 | 41 | ### 1.1 Keycloak IdP realm discovery 42 | 43 | Keycloak offers standard OIDC service discovery via `.well-known` documents to advertise its endpoints. 44 | 45 | In SCS we want to represent each customer by a separate dedicated Keycloak realm, which can enventually be used 46 | for customer self service and to federate out to customer owned IAM external solutions. 47 | 48 | In the SCS testbed we currently experiment with the implications of using a single central proxy realm in Keycloak 49 | and chaining federation from there to customer specific realms, also hosted in the same Keycloak instance. 50 | To make this usable, SCS makes use of the 51 | [Keycloak Home IdP Discovery](https://github.com/sventorben/keycloak-home-idp-discovery) 52 | extension. 53 | 54 | ### 1.2 Keystone mapping of token claims 55 | 56 | Upon login of a user Keystone evaluates the credentials obtained from the ID token that the IdP issued. 57 | These include group memberships and roles, which can be used to assign the user to a certain project. 58 | Keystone maps these external identities to internal (shadow) users. 59 | It can either attempt to map the obtained information to a `local` type user, which needs to be 60 | provisioned before authentication by external tooling, or it can be instructed via the mapping to 61 | generate an `ephemeral` type user. `ephemeral` users are cleaned up automatically after some time 62 | of inactivity and with that, they lose access to projects, iff the access is granted indirectly 63 | via group membership rather than directly to the user itself. 64 | 65 | Group memberships for `ephemeral` users are only represented via their tokens, but not stored in the 66 | Keystone backend database. 67 | 68 | After successful authorization Keystone issues an OpenStack specific `fernet` token to the user, 69 | which is the currency that is understood by other OpenStack services and can be used to access them. 70 | 71 | In SCS we want to represent each customer by a sepatate dedicated OpenStack domain to host 72 | their projects and (shadow) user accounts. 73 | 74 | The processing of information from the OIDC tokens is configured by two parts. The first part is the 75 | `rules.json` mapping which is described in the 76 | [OpenStack federation mapping combinations](https://docs.openstack.org/keystone/latest/admin/federation/mapping_combinations.html) 77 | document. This file is used to configure Keystones internal mapping engine 78 | and it needs to be attached to some OpenStack domain, which is named `keycloak` by default in SCS. 79 | 80 | The second (static) part is the `[auth]` and `[mapped]` sections in `keystone.conf` (see e.g. 81 | [the overlays currently used in the OSISM testbed](https://github.com/osism/testbed/tree/main/environments/kolla/files/overlays/keystone) 82 | ). 83 | 84 | ### 1.3 Horizon WebSSO for federated users 85 | 86 | The Horizon dashboard supports login via OpenID Connect via Keystone endpoint. 87 | SCS adjusted the logout behavior to invalidate both, the OpenID Connect session 88 | with the IdP and the Keystone token. 89 | 90 | ### 1.4 OpenStack CLI and API access for federated users 91 | 92 | To support OpenStack CLI and API access, SCS implemented support for the OIDC Device Authorization Grant 93 | in Keystone. On top we added support for PKCE (RFC 7636) in combination with that. 94 | 95 | ### 1.5 SSO Federation between to SCS deployments 96 | 97 | To show the potential of this approach to federation SCS created a 98 | [Howto for OIDC federation between SCS deployments](https://docs-staging.scs.community/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations). 99 | -------------------------------------------------------------------------------- /docs/05-iam/intra-SCS-federation-setup-description-for-osism-doc-operations.md: -------------------------------------------------------------------------------- 1 | # Proposal for documentation for Keycloak to Keycloak Federation (WebSSO) 2 | 3 | The followig section is a reasonably detailed hands on description of how 4 | to configure a federation between two separate SCS compliant domains by means 5 | of Keycloak `Identity Brokering`. If we decide to use Keycloak as a component 6 | to allow self service by tenants, then this documentation may be a useful addition 7 | to some tenant facing documentation (or for the SCS operators too). 8 | 9 | OTOH one could probably also script pretty much everything of this to allow 10 | tenants to use a CLI tool to automate the setup. For that purpose the documentation 11 | may be useful to guide the implementation of such a scripted solution. 12 | 13 | ## Detailed tutorial on how to configure Federation (OpenID Connect) between two Keycloak instances in two separate SCS domains 14 | 15 | Assume you have two CSPs using SCS. The first one wants to grant access to users of the other. 16 | So let's call the first domain "resource domain" and the second one "accounts domain". 17 | Both domains need to agree upon a name for the "OIDC RP" (which Keycloak calls `Clients`). 18 | The Keycloak in the "resource domain" will be the OIDC RP and the Keycloak in the "accounts domain" will be the OIDC OP. 19 | Assuming the "resource domain" is called `foo` and the "accounts domain" is called bar, the name for the "OIDC RP" could be `oidc-rp-foo`. 20 | 21 | 1. In the accounts domain (`bar`) open Keycloak realm `osism`, click on `Clients` in the sidebar and click on `Create client`. 22 | Leave the client type as `OpenID Connect` and enter the `Client ID`, e.g. `oidc-rp-foo`. 23 | Turn on `Client authentication` for it and click `Save`. 24 | 25 | On the `Client details` page open the tab `Credentials` and copy the `Client secret`. Communicate this to the operato of the "resource domain" `foo` via a secure channel. 26 | 27 | 2. In the resource domain (`foo`) open Keycloak realm `osism`, click on `Identity providers` 28 | and create a new provider definition of type `OpenID Connect v1.0`. As `Alias` choose a name, 29 | e.g. `oidc-op-bar`. Don't copy the `Redirect URI` given at the top yet, because is will change depending 30 | on the chosen `Alias`. Instead, scroll down to the mandatory field `Discovery endpoint` and paste 31 | the OpenID Connect metadata URL of the KEycloak realm `osism` in the "accounts domain" (`bar`). 32 | The operator of the "accounts domain" (`bar`) may easily copy that URL from the `Realm Settins` in the 33 | sidebar of his Keycloak instance, where the `Endpoints` are listed on the bottom of that form. 34 | The URL may have the format `https://bar.com/auth/realms/osism/.well-known/openid-configuration`. 35 | Once you leave that input field, Keycloak will attempt to fetch the metadata and extract the required 36 | details about protocol enspoints from the retrieved document. If this shows an error, it will give you 37 | an HTTP status code. If this shows an error code of 500, then this may be caused by a failure in 38 | certificate verification. In that case you may want to check the output of `docker logs keycloak` for 39 | java stack traces. If you find any, the top of those stack traces may indicate what kind of problem 40 | occurred to the java code. From here we will assume that the emtadata URL could be fecthed without 41 | any issues. 42 | 43 | Now, go to the bottom of that form and insert tjhe `Client ID` (`oidc-rp-foo`) and the 44 | `Client secret` that was provided by the operator of the "accounts domain" (`bar`). 45 | Finally click on `Add`. From the `Provider Details` page on the top for the `Settings` tab copy the value of the 46 | `Redirect URI` and communicate it back to the operator of the "accounts domain" (`bar`). 47 | 48 | 3. In the accounts domain (`bar`) open Keycloak realm `osism`, click on `Clients` in the sidebar and click 49 | on the name of the OIDC RP clinent that you created for domain `foo` (e.g. `oidc-rp-foo`). 50 | On the `Client details` page on the tab `Settings` fill in the field `Valid redirect URIs` with the value 51 | obtained from the resource domain (`foo`), which should look similar to 52 | `https://foo.com/auth/realms/osism/broker/oidc-op-bar/endpoint`. Additionally the 53 | `Valid post logout redirect URIs` need to be set to something like `https://foo.com/auth/realms/osism/*`. 54 | 55 | 4. To test federated login in the "resource domain" (`foo`) open the URL of the Keycloak admin console for 56 | the realm `osism`: `https://foo.com/auth/admin/osism/console` (or `https://foo.com/auth/realms/osism/protocol/openid-connect/auth?client_id=security-admin-console`). 57 | Ignore the top section of the login form titled 58 | `Sign in to your account` and choose one of the OIDC OP federation choises below the line `Or sign in with`. 59 | In this example it would be `oidc-op-bar`. This should redirect your browser to the authentication endpoint 60 | of the "accounts domain" (`https://bar.com/auth/realms/osism/protocol/openid-connect/auth?scope=openid&...`) 61 | where you should be able to log in with credentials that are valid in the "accounts domain" (`bar`). 62 | After successull authentication your broser should be redirected to admin console of the "resource domain", 63 | which may offer you a "first login flow" form where you can choose a username, email, firstname and lastname. 64 | The details depend on the `Mappers` that have been configured for the Identity Provider `oidc-op-bar`. 65 | After that you will be presented with a Keycloak themed page with the error message `Request failed with status code 403`, 66 | which is normal because the test account is not authorized to access any elements of the Keycloak admin console. 67 | -------------------------------------------------------------------------------- /user-docs/usage-hints/find-image/find_img.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # find_img.py 4 | # 5 | # Searches for an image with distribution and version and purpose 6 | # 7 | # (c) Kurt Garloff , 7/2025 8 | # SPDX-License-Identifier: MIT 9 | "This module finds the a distribution image with a given purpose" 10 | 11 | import os 12 | import sys 13 | import openstack 14 | # import logging 15 | 16 | 17 | def warn(log, msg): 18 | "warn output" 19 | if log: 20 | log.warn(msg) 21 | else: 22 | print(f"WARN: {msg}", file=sys.stderr) 23 | 24 | 25 | def debug(log, msg): 26 | "debug output" 27 | if log: 28 | log.debug(msg) 29 | else: 30 | print(f"DEBUG: {msg}", file=sys.stderr) 31 | 32 | 33 | def img_sort_heuristic(images, distro, version, purpose): 34 | """Sort list to prefer old names""" 35 | # Do sorting magic (could be omitted) 36 | newlist = [] 37 | distro = distro.lower() 38 | version = version.lower() 39 | purpose = purpose.lower() 40 | # 0th: Exact match old SCS naming scheme ("Ubuntu 24.04 Minimal") 41 | for img in images: 42 | newel = (img.id, img.name) 43 | if img.name.lower() == f"{distro} {version} {purpose}": 44 | newlist.append(newel) 45 | elif img.name.lower() == f"{distro} {purpose} {version}": 46 | newlist.append(newel) 47 | # 1st: Exact match old SCS naming scheme ("Ubuntu 24.04") 48 | for img in images: 49 | newel = (img.id, img.name) 50 | if img.name.lower() == f"{distro} {version}": 51 | newlist.append(newel) 52 | # 2nd: Fuzzy match old SCS naming scheme ("Ubuntu 24.04*") 53 | for img in images: 54 | newel = (img.id, img.name) 55 | if img.name.lower().startswith(f"{distro} {version}") and newel not in newlist: 56 | newlist.append(newel) 57 | # 3rd: Even more fuzzy match old SCS naming scheme ("Ubuntu*24.04") 58 | for img in images: 59 | newel = (img.id, img.name) 60 | if img.name.lower().startswith(f"{distro}") and img.name.lower().endswith(f"{version}") \ 61 | and newel not in newlist: 62 | newlist.append(newel) 63 | # 4th: Rest 64 | for img in images: 65 | newel = (img.id, img.name) 66 | if newel not in newlist: 67 | newlist.append(newel) 68 | return newlist 69 | 70 | 71 | def find_image(conn, distro, version, purpose="generic", strict=False, log=None): 72 | """Return a sorted list of ID,Name pairs that contain the wanted image. 73 | Empty list indicates no image has been found. The list is sorted such 74 | that (on SCS-compliant clouds), it will very likely contain the best 75 | matching, most recent image as first element. 76 | If strict is set, multiple matches are not allowed. 77 | """ 78 | ldistro = distro.lower() 79 | # FIXME: The image.images() method only passes selected filters 80 | purpose_out = purpose 81 | images = [x for x in conn.image.images(os_distro=ldistro, os_version=version, 82 | sort="name:desc,created_at:desc", visibility="public") 83 | if x.properties.get("os_purpose") == purpose] 84 | if len(images) == 0: 85 | warn(log, f"No image found with os_distro={ldistro} os_version={version} os_purpose={purpose}") 86 | purpose_out = "" 87 | # images = list(conn.image.images(os_distro=ldistro, os_version=version, 88 | # sort="name:desc,created_at:desc")) 89 | images = [x for x in conn.image.images(os_distro=ldistro, os_version=version, 90 | sort="name:desc,created_at:desc") 91 | if "os_purpose" not in x.properties] 92 | if len(images) == 0: 93 | warn(log, f"No image found with os_distro={ldistro} os_version={version} without os_purpose") 94 | return [] 95 | # Now comes sorting magic for best backwards compatibility 96 | if len(images) > 1: 97 | debug(log, f"Several {purpose_out} images found with os_distro={ldistro} os_version={version}") 98 | if strict: 99 | return [] 100 | return img_sort_heuristic(images, distro, version, purpose) 101 | return [(img.id, img.name) for img in images] 102 | 103 | 104 | def usage(): 105 | "Usage hints (CLI)" 106 | print("Usage: find-img.py [-s] DISTRO VERSION [PURPOSE]", file=sys.stderr) 107 | print("Returns all images matching, latest first, purpose defaulting to generic", file=sys.stderr) 108 | print("[-s] sets strict mode where only one match is allowed.", file=sys.stderr) 109 | print("You need to have OS_CLOUD set when running this", file=sys.stderr) 110 | sys.exit(1) 111 | 112 | 113 | def main(argv): 114 | "Main entry for CLI" 115 | if len(argv) < 3: 116 | usage() 117 | try: 118 | conn = openstack.connect(cloud=os.environ["OS_CLOUD"]) 119 | except openstack.exceptions.ConfigException: 120 | print(f"No valid entry for cloud {os.environ['OS_CLOUD']}", file=sys.stderr) 121 | usage() 122 | except KeyError: 123 | print("OS_CLOUD environment not configured", file=sys.stderr) 124 | usage() 125 | conn.authorize() 126 | purpose = "generic" 127 | strict = False 128 | if argv[1] == "-s": 129 | argv = argv[1:] 130 | strict = True 131 | if len(argv) > 3: 132 | purpose = argv[3] 133 | images = find_image(conn, argv[1], argv[2], purpose, strict) 134 | for img in images: 135 | print(f"{img[0]} {img[1]}") 136 | return len(images) == 0 137 | 138 | 139 | if __name__ == "__main__": 140 | sys.exit(main(sys.argv)) 141 | -------------------------------------------------------------------------------- /community/contribute/styleguides/ansible_styleguide.md: -------------------------------------------------------------------------------- 1 | # Ansible Style Guide 2 | 3 | We use nearly all default rules of ansible lint. A listing of all these rules can be found in the Ansible Lint documentation: 4 | [https://ansible.readthedocs.io/projects/lint/rules/](https://ansible.readthedocs.io/projects/lint/rules/). 5 | Please always use the ansible linting to check if the code complies with the default linting rules. 6 | However, since in most cases we always use the latest version of packages and Ansible lint does not provide this, we decided to 7 | disable the package_latest rule. 8 | 9 | ## Task naming 10 | 11 | - Tasks must always have names. The only exception allowed is for forked playbooks. 12 | - A name never starts with a small letter 13 | - Names are written in present tense 14 | - No punctuation is used in names 15 | 16 | ## Key Order 17 | 18 | To check the key order we use our own rule. This can be found [here](https://github.com/osism/zuul-jobs/tree/main/roles/ansible-lint/files). 19 | 20 | ### Positioning and use of the become directive 21 | 22 | The become directive is only set when needed and is always set explicitly for each task that needs it. 23 | 24 | Blocks, roles or playbooks are never executed in a privileged mode. 25 | 26 | We always insert the become directive between the name of a task and the task itself. This also applies to related directives 27 | like _become_user_ or _become_flags_. This is for better visibility if a task is privileged or not. 28 | 29 | ```yaml 30 | - name: Copy hddtemp configuration file 31 | become: true 32 | ansible.builtin.copy: 33 | src: "{{ ansible_os_family }}/hddtemp" 34 | dest: "{{ hddtemp_conf_file }}" 35 | owner: root 36 | group: root 37 | mode: 0644 38 | notify: Restart hddtemp service 39 | ``` 40 | 41 | ### Position of the when condition 42 | 43 | If you need to use the when condition please add this at the end-section from the task where it is needed. This makes the code 44 | easier to understand for others. Ansible lint provides the when condition under the task name for blocks. To keep the code clear 45 | we decided against it. Please disable this with a noqa if necessary. For example: 46 | 47 | ```yaml 48 | - name: "Archive existing {{ resolvconf_file }} file" 49 | become: true 50 | ansible.posix.synchronize: 51 | src: "/etc/resolv.conf" 52 | dest: "/etc/resolv.conf.{{ ansible_date_time.date }}" 53 | archive: true 54 | delegate_to: "{{ inventory_hostname }}" 55 | when: stat_resolvconf_file.stat.islnk is defined and not stat_resolvconf_file.stat.islnk 56 | ``` 57 | 58 | ## Usage of collections 59 | 60 | Collections are always defined as in the following example. 61 | 62 | **netbox.netbox** is here the collection that is used. 63 | 64 | ```yaml 65 | - name: Configure netbox manufacturers 66 | netbox.netbox.netbox_manufacturer: 67 | netbox_url: '{{ netbox_url }}' 68 | netbox_token: '{{ netbox_token }}' 69 | data: 70 | name: '{{ item.value.name }}' 71 | slug: '{{ item.value.slug }}' 72 | description: "{{ item.value.description | default('') }}" 73 | state: present 74 | with_dict: '{{ netbox_data_manufacturers }}' 75 | ``` 76 | 77 | Please don´t declare it in this way!: 78 | 79 | ```yaml 80 | collections: 81 | - netbox.netbox 82 | 83 | tasks: 84 | - name: Manage Discworld site 85 | netbox_site: 86 | netbox_url: "{{ netbox_url }}" 87 | netbox_token: "{{ netbox_token }}" 88 | validate_certs: false 89 | data: 90 | name: Discworld 91 | slug: discworld 92 | state: present 93 | ``` 94 | 95 | If you have to use collections please define them in a requirements.yml. 96 | 97 | Example yaml: 98 | 99 | ```yaml 100 | roles: 101 | - name: geerlingguy.certbot 102 | version: master 103 | type: git 104 | src: git+https://github.com/geerlingguy/ansible-role-certbot.git 105 | --- 106 | collections: 107 | - name: ansible.netcommon 108 | source: https://galaxy.ansible.com 109 | 110 | - name: https://github.com/ansible-collections/ansible.posix.git 111 | type: git 112 | version: main 113 | ``` 114 | 115 | ## Usage of roles from other collections 116 | 117 | If you want to reuse roles please do it in the following way: 118 | 119 | First you have to declare the role or collection in the requirements.yml like shown in the example before. 120 | 121 | Than you can use it in playbooks like this 122 | 123 | ```yaml 124 | roles: 125 | - role: osism.services.auditd 126 | ``` 127 | 128 | ## Parameters that offer lists 129 | 130 | Parameters that provide a list are always defined as in the following example. 131 | 132 | **docker_hosts_defaults** sets the defaults in the role. Overriding is only possible with the **ansible-defaults** repository. 133 | 134 | In the configuration repository, docker_hosts_extra is then used to add additional items to the list. 135 | 136 | **docker_hosts** itself is never modified from the outside. 137 | 138 | ```yaml 139 | docker_hosts_defaults: 140 | - 'unix:///var/run/docker.sock' 141 | docker_hosts_extra: [] 142 | docker_hosts: '{{ docker_hosts_defaults + docker_hosts_extra }}' 143 | ``` 144 | 145 | ## Usage of changed_when 146 | 147 | Please think twice before turning off changed_when. It's a fairly simple yet safety-relevant linting rule and is quite easy to 148 | implement. 149 | 150 | ## Disable linting rules 151 | 152 | In principle, it is only allowed to disable rules if there is really no other possibility. 153 | Please do not disable rules in general but only in individual cases via Noqa. Please use in this case the full rulename and not 154 | the numbers, because them are depricated. If it makes sense to ignore a rule, please open up an issue in the 155 | [https://github.com/osism/issues](https://github.com/osism/issues) repository with a label discussion. 156 | -------------------------------------------------------------------------------- /community/cloud-resources/cloud-resources.md: -------------------------------------------------------------------------------- 1 | # Test and development cloud resources 2 | 3 | This document gives an overview of the test and development cloud resources currently provided by our partners. 4 | 5 | ## How to request cloud resources 6 | 7 | To request access to an existing project, please contact the responsible community member. To apply for a new project, please create a pull request against this document (leave `Unique Identifier` blank) and assign it to the particular CSP team (e.g. @SovereignCloudStack/plusserver, @SovereignCloudStack/wavecon, ...) 8 | 9 | ## plusserver (SCS2) 10 | 11 | SCS2 is the successor to gx-scs (or SCS1), which no longer exists. 12 | 13 | ### SCS2 Usage 14 | 15 | A brief guide on how to use the resources provided by plusserver GmbH can be found [here](plusserver-gx-scs.md) 16 | 17 | ### SCS2 Users 18 | 19 | As suggested in [#155](https://github.com/SovereignCloudStack/standards/issues/155) the username for non-"service users" will contain the users github handle and are prefixed with a plusserver default. 20 | `prefix-<$github handle>` 21 | 22 | > **Note** 23 | > ATM this is not directly connected to the SovereignCloudStack github org membership, accounts will be created manually for now. 24 | 25 | 26 | 27 | Example: 28 | 29 | | github handle | plusserver login | 30 | | :-----------: | :-----------------: | 31 | | frosty-geek | u500924-frosty-geek | 32 | | fkr | u500924-fkr | 33 | | | | 34 | 35 | ### SCS2 Service Users 36 | 37 | Service users will have their default_project_id set to a specific project and will NOT be granted full access to other projects by default. 38 | 39 | | Unique Identifier | Service User Name | Full Access on | Community Contact | Description | Needed until | 40 | | :------------------------------: | -------------------------- | ------------------------- | ------------------------ | --------------------------------------------- | :----------: | 41 | | 9a1576af59644a2dbbace773ad17158d | u500924-svc-sig-monitoring | p500924-sig-monitoring1 | fkr | Service User - SIG Monitoring | 31.12.2023 | 42 | | 4925967416894fd78be6701689059653 | u500924-svc-cloudmon | p500924-cloudmon-target | Erik-Kostelansky-dNation | Service User - VP12 Test Project | 31.12.2024 | 43 | | f89b3d64ddff4d9d8cadb5e06fa22299 | u500924-svc-healthmonitor | p500924-scs-healthmonitor | garloff | Service User - SCS Health Monitor | ∞ | 44 | | 49cc3d72fbdf41fe8dc407f57f026dbf | u500924-svc-standards | p500924-scs-healthmonitor | garloff | Service User - SCS Standards Compliance Check | ∞ | 45 | | 1b6bb583fc5e40e49f2a7e9b4301de65 | u500924-svc-zuul | p500924-scs-zuul | o-otte | Service User - SCS Zuul | 30.11.2024 | 46 | | | | | | | | 47 | 48 | ### SCS2 Projects 49 | 50 | | Unique Identifier | Project Name | Community Contact | Description | Needed until | 51 | | :------------------------------: | --------------------------- | ----------------- | --------------------------------- | :----------: | 52 | | 9c482c928d68470ea35a764e1ba9211a | p500924-compliance-monitor | mbuechse | SCS Compliance Monitor Deployment | ∞ | 53 | | fe66fd7655814078924155876562dd3d | p500924-scs-community | fkr | SCS Community Project | ∞ | 54 | | | p500924-compliance-monitor | depressiveRobot | SCS Compliance Monitor Deployment | ∞ | 55 | | 4a8829a5ecad480d8dde1e46a9c5284b | p500924-health-monitor | garloff | SCS Health Monitor | ∞ | 56 | | 34d3d89fc74e4db5a6df1c9ebf2f3a2a | p500924-scs-zuul | garloff | SCS Zuul | ∞ | 57 | | 293b765e3492413ba8b0067b7edcb3a3 | p500924-monitoring | garloff | SCS Monitoring | ∞ | 58 | | f2eccb67b16f4430b6d5e70afb515f9d | p500924-harbor | chess-knight | SCS Registry (Harbor) | ∞ | 59 | | 45b5e27a5fe3431083e450cf2d13e71b | p500924-kaas-playground1 | jschoone | Playground1 for Hackathon | 30.09.2025 | 60 | | ef12fed77f114eb4a20068f0422a8109 | p500924-kaas-playground2 | jschoone | Playground2 for Hackathon | 30.09.2025 | 61 | | bf8d511728a44072b7c97b1fe00947b8 | p500924-kaas-playground3 | jschoone | Moin Cluster | ∞ | 62 | | 61b315797c75431787dc20a61cbaf052 | p500924-kaas-playground4 | jschoone | Playground4 for Hackathon | 30.09.2025 | 63 | | 94f7c7507be1484a9ce6aba20d19d1c6 | p500924-kaas-playground5 | jschoone | Playground5 for Hackathon | 30.09.2025 | 64 | | | p500924-openDesk-playground | gerbsen | Playground for openDesk | 30.11.2025 | 65 | 66 | ## Wavecon 67 | 68 | ### Wavestack Service Users 69 | 70 | | Unique Identifier | Service User Name | Full Access on | Community Contact | Description | Needed until | 71 | | :------------------------------: | ----------------- | -------------- | ----------------- | --------------------------------------------- | :----------: | 72 | | df4af5376bbd4de587c4335622149be7 | scs-standards | scs-standards | itrich | Service User - SCS Standards Compliance Check | ∞ | 73 | 74 | ### Wavestack Projects 75 | 76 | | Unique Identifier | Project Name | Community Contact | Description | Needed until | 77 | | :------------------------------: | ------------------ | ----------------- | ------------------ | :----------: | 78 | | 718964b4b87446688ac04b151519fb51 | scs | garloff | SCS Health Monitor | ∞ | 79 | | c46ccc9e695c4b23bacee2ad11145d9a | scs-health-monitor | garloff | SCS Health Monitor | ∞ | 80 | | 00de553df86949b49365baee6375fb5a | scs-standards | itrich | SCS Health Monitor | ∞ | 81 | 82 | 83 | -------------------------------------------------------------------------------- /contributor-docs/development/tests/test-implementation-guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: SCS Conformance Test Implementation Guide 3 | type: 4 | status: Draft 5 | track: Global 6 | --- 7 | 8 | SovereignCloudStack (SCS) uses [conformance tests][gh-scripts] to certify 9 | compliance of a given cloud offering with respect to a given [certificate 10 | scope][cert-scopes] such as *SCS Compatible IaaS v4*. 11 | Our aim is that these tests are reliable, consistent and comprehensible for 12 | the users. 13 | This document is a guideline for conformance test authors and summarizes the 14 | current best practices to achieve this goal. 15 | 16 | ## 1. Mapping of RFC2119 Keywords 17 | 18 | Test authors working on new and existing conformance tests for an SCS standard 19 | must implement the keywords such as MUST and SHOULD according to the [SCS 20 | RFC2119 Keyword Test Guide][scs-rfc2119-guide]. 21 | 22 | ## 2. Unit and Regression Tests 23 | 24 | Test authors are *strongly* encouraged to include unit and regression tests for 25 | the conformance test's logic. 26 | Conformance tests will inevitably contain some non-trivial algorithms, be it for 27 | parsing flavor names or evaluating CVE vulnerability reports. 28 | Testing them automatically and regularly against valid and invalid inputs helps 29 | test authors to find programming mistakes early on. 30 | As a bonus, a well written unit test also makes it easier for reviewers to cross 31 | check a given pull request with new, enhanced or refactored conformance tests. 32 | 33 | In general, unit and regression tests for the conformance tests are located in 34 | the same location as the conformance tests, that is, the `Tests/` directory of 35 | the [SCS standards repository][scs-standards]. 36 | Setup and development of the unit tests is described in the [SCS conformance 37 | tests README][tests-readme]. 38 | 39 | ### Naming Conventions 40 | 41 | Any module that ends in `_test` will be picked up as a unit test module by 42 | pytest in our CI pipeline (in other words, all files matched by the pattern 43 | `Tests/**/*_test.py`). 44 | Pytest will execute any function prefixed with `test_` as a test function, or, 45 | alternatively, tests based on the `unittest` module from the Python standard 46 | library. 47 | 48 | Follow these naming rules: 49 | 50 | * The name of a unit test module is constructed from the module to be unit 51 | tested and the `_test` suffix. For example, unit tests for `flavor_names.py` 52 | should reside in `flavor_names_test.py`. 53 | * The name of a Python module in general should be a valid [Python 54 | identifier][python-identifiers], to allow imports via the `import` statement. 55 | For example, use `flavor_names.py` instead of `flavor-names.py`. 56 | 57 | ### Write Testable Conformance Tests 58 | 59 | Software design fills complete book shelves and this section can only cover some 60 | basic best practices. 61 | As a general rule of thumb, the earlier you begin writing unit tests, the better 62 | – it will force you to write modules that are easy to test. 63 | 64 | Divide conformance tests scripts into smaller, loosely coupled units, i.e., 65 | functions that serve one purpose each. 66 | Use the [*dependency injection*][wiki-di] technique, i.e., pass externally 67 | retrieved data as function arguments instead of hardcoding the calls to the 68 | retrieval functions inside a function. 69 | Avoid logging calls deep down in the call hierarchy and use explicit return 70 | values or raise exceptions, instead. 71 | Here is an abstract example of a conformance test which does exactly that: 72 | 73 | ```python 74 | # property_compliance.py 75 | 76 | def retrieve(location): 77 | """Retrieve raw data via network.""" 78 | ... 79 | 80 | def parse(data): 81 | """Parse raw data and return a dict.""" 82 | ... 83 | 84 | def handle(...): 85 | """Evaluate parsed data.""" 86 | ... 87 | 88 | def main(args): 89 | ... 90 | data = retrieve(location) 91 | parsed = parse(data) 92 | result = handle(parsed) 93 | ... 94 | if result.some_prop != expected_value: 95 | logging.warn("some_prop is not as expected: %s (vs. %s)", result.some_prop, expected_value) 96 | ... 97 | return result.success 98 | 99 | if __name__ == "__main__": 100 | # using sys.exit(…) only here makes it possible to unit test main(…) 101 | sys.exit(main(sys.argv)) 102 | ``` 103 | 104 | Adhering to this style makes it easier to test an algorithm in isolation, 105 | without actually making a call to some external service. 106 | 107 | ### Pytest Test Example 108 | 109 | Assuming we want to unit test some members of the module `property_compliance` 110 | from the previous section, we would create a file `property_compliance_test.py` 111 | with the following content as a starting point: 112 | 113 | ```python 114 | """Unit tests for property_compliance. 115 | 116 | (c) Your Name , 4/2024 117 | SPDX-License-Identifier: CC-BY-SA-4.0 118 | """ 119 | 120 | import pytest 121 | 122 | from property_compliance import parse 123 | 124 | 125 | def test_success(): 126 | assert parse("some valid input") == "expected output" 127 | 128 | 129 | def test_failure(): 130 | with pytest.raises(ValueError): 131 | parse("invalid input") 132 | ``` 133 | 134 | ## 3. Conformance Tests Shouldn't Require Admin Privileges 135 | 136 | Conformance tests are expected to be executable without admin privileges (see §2 of 137 | [Regulations for achieving SCS-compatible certification][scs-0004-v1]). 138 | In particular, this means: 139 | 140 | * The cloud credentials (e.g., kubeconfig and OpenStack `clouds.yaml`) passed to 141 | the scripts are non-admin credentials. 142 | * Conformance tests scripts should not require root privileges, except for the 143 | installation of operating system prerequisites (e.g., a Python interpreter). 144 | 145 | [scs-standards]: https://github.com/SovereignCloudStack/standards/ 146 | [tests-readme]: https://github.com/SovereignCloudStack/standards/blob/main/Tests/README.md 147 | [python-identifiers]: https://docs.python.org/3/reference/lexical_analysis.html#identifiers 148 | [gh-scripts]: https://github.com/SovereignCloudStack/standards/tree/main/Tests 149 | [cert-scopes]: https://docs.scs.community/standards/certification/scopes-versions 150 | [scs-rfc2119-guide]: https://docs.scs.community/contributor-docs/operations/tests/rfc2119-keyword-test-guide 151 | [scs-0004-v1]: https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0004-v1-achieving-certification.md 152 | [wiki-di]: https://en.wikipedia.org/wiki/Dependency_injection 153 | -------------------------------------------------------------------------------- /user-docs/usage-hints/find-image/find_img.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Logic to identify image with given os_distro, os_version, os_purpose 3 | # Simply find the image for new SCS clouds that have os_purpose set. 4 | # Fall back to name matching otherwise. 5 | # (c) Kurt Garloff , 11/2025 6 | # SPDX-License-Identifier: MIT 7 | # Created with help from Claude AI 8 | 9 | - name: Select Image with purpose and fall back to name matching 10 | hosts: localhost 11 | gather_facts: false 12 | vars: 13 | # Primary selection criteria 14 | os_version: '24.04' 15 | os_distro: 'ubuntu' 16 | os_purpose: 'generic' 17 | cloud_name: "{{ lookup('env', 'OS_CLOUD') | default('openstack') }}" 18 | 19 | tasks: 20 | - name: Get available images matching os_distro and os_version 21 | openstack.cloud.image_info: 22 | cloud: '{{ cloud_name }}' 23 | properties: 24 | os_distro: '{{ os_distro }}' 25 | os_version: '{{ os_version }}' 26 | register: _distro_images 27 | 28 | - name: 'Show images that match {{os_distro}} {{os_version}}' 29 | debug: 30 | msg: '{{ _distro_images.images | to_nice_json }}' 31 | 32 | - name: 'First choice: Match os_purpose' 33 | set_fact: 34 | _primary_images: >- 35 | {{ 36 | _distro_images.images 37 | | selectattr('properties.os_purpose', 'defined') 38 | | selectattr('properties.os_purpose', 'equalto', os_purpose) 39 | | list 40 | }} 41 | 42 | - name: 'Select primary image if found' 43 | set_fact: 44 | selected_image: >- 45 | {{ 46 | _primary_images 47 | | sort(attribute='created_at', reverse=true) 48 | | sort(attribute='name', reverse=true) 49 | | first 50 | }} 51 | match_type: 'primary' 52 | when: _primary_images | length > 0 53 | 54 | # Fallback logic - only executed if no primary match 55 | - block: 56 | - name: 'Fallback 1 pattern' 57 | set_fact: 58 | _pattern1: "(?i){{ os_distro | regex_escape }}\\s+{{ os_version | regex_escape }}\\s+{{ os_purpose | regex_escape }}.*" 59 | - name: "Fallback 1: Filter images without os_purpose, matching name pattern '{{ os_distro }} {{ os_version }} {{ os_purpose }}'" 60 | set_fact: 61 | _fallback1_images: >- 62 | {{ 63 | _distro_images.images 64 | | rejectattr('properties.os_purpose', 'defined') 65 | | selectattr('name', 'search', _pattern1) 66 | | list 67 | }} 68 | - name: Select fallback 1 match if found 69 | set_fact: 70 | selected_image: >- 71 | {{ 72 | _fallback1_images 73 | | sort(attribute='created_at', reverse=true) 74 | | sort(attribute='name', reverse=true) 75 | | first 76 | }} 77 | match_type: 'fallback_pattern1' 78 | when: _fallback1_images | length > 0 79 | when: _primary_images | length == 0 80 | 81 | - block: 82 | - name: 'Fallback 2 pattern' 83 | set_fact: 84 | _pattern2: "(?i){{ os_distro | regex_escape }}\\s+{{ os_purpose | regex_escape }}\\s+{{ os_version | regex_escape }}.*" 85 | - name: "Fallback 2: Filter images without os_purpose, matching name pattern '{{ os_distro }} {{ os_purpose }} {{ os_version }}'" 86 | set_fact: 87 | _fallback2_images: >- 88 | {{ 89 | _distro_images.images 90 | | rejectattr('properties.os_purpose', 'defined') 91 | | selectattr('name', 'search', _pattern2) 92 | | list 93 | }} 94 | - name: Select fallback 2 match if found 95 | set_fact: 96 | selected_image: >- 97 | {{ 98 | _fallback2_images 99 | | sort(attribute='created_at', reverse=true) 100 | | sort(attribute='name', reverse=true) 101 | | first 102 | }} 103 | match_type: 'fallback_pattern2' 104 | when: _fallback2_images | length > 0 105 | when: 106 | - _primary_images | length == 0 107 | - _fallback1_images | default([]) | length == 0 108 | 109 | - block: 110 | - name: 'Fallback 3 pattern' 111 | set_fact: 112 | _pattern3: "(?i){{ os_distro | regex_escape }}\\s+{{ os_version | regex_escape }}.*" 113 | - name: "Fallback 3: Filter images without os_purpose, matching name pattern '{{ os_distro }} {{ os_version }}'" 114 | set_fact: 115 | _fallback3_images: >- 116 | {{ 117 | _distro_images.images 118 | | rejectattr('properties.os_purpose', 'defined') 119 | | selectattr('name', 'search', _pattern3) 120 | | list 121 | }} 122 | - name: Select fallback 3 match if found 123 | set_fact: 124 | selected_image: >- 125 | {{ 126 | _fallback3_images 127 | | sort(attribute='created_at', reverse=true) 128 | | sort(attribute='name', reverse=true) 129 | | first 130 | }} 131 | match_type: 'fallback_pattern3' 132 | when: _fallback3_images | length > 0 133 | when: 134 | - _primary_images | length == 0 135 | - _fallback1_images | default([]) | length == 0 136 | - _fallback2_images | default([]) | length == 0 137 | 138 | - name: Display selected image 139 | debug: 140 | msg: 141 | - 'Match Type: {{ match_type }}' 142 | - 'Image Name: {{ selected_image.name }}' 143 | - 'Image ID: {{ selected_image.id }}' 144 | - 'Created: {{ selected_image.created_at }}' 145 | - 'Properties: {{ selected_image.properties }}' 146 | when: selected_image is defined 147 | 148 | - name: Fail if no suitable image found 149 | fail: 150 | msg: | 151 | No suitable image found matching criteria: 152 | - os_distro: {{ os_distro }} 153 | - os_version: {{ os_version }} 154 | - os_purpose: {{ os_purpose }} 155 | 156 | Tried: 157 | 1. Images with os_purpose property = '{{ os_purpose }}' 158 | 2. Images matching name pattern '{{ os_distro }} {{ os_version }} {{ os_purpose }}' 159 | 3. Images matching name pattern '{{ os_distro }} {{ os_purpose }} {{ os_version }}' 160 | 4. Images matching name pattern '{{ os_distro }} {{ os_version }}' 161 | when: selected_image is not defined 162 | -------------------------------------------------------------------------------- /community/tools/jitsi.md: -------------------------------------------------------------------------------- 1 | # Jitsi 2 | 3 | We use a self-hosted [Jitsi Meet](https://jitsi.org) instance for video conferencing. 4 | Thanks go to Cleura for providing the server VM for it. 5 | 6 | Jitsi has served us well, providing good quality and reliable VC service while allowing 7 | multiple screen shares and conferences with (at least) up to 50 video participants. 8 | 9 | The server uses an automated deployment based on the 10 | [heat-docker-jitsi-meet](https://github.com/garloff/heat-docker-jitsi-meet) project. 11 | 12 | Configuration is such everyone who knows the room can connect, unless the moderator 13 | sets a password/PIN. Opening a new room requires authentication. (Contact 14 | [Kurt](https://github.com/garloff) if you need a password.) 15 | 16 | Links to the meeting room (as well as dial-in information) are in the appointments 17 | in the public calendar. 18 | 19 | ## Usage 20 | 21 | Connect with a desktop browser, the Jitsi [desktop app](https://github.com/jitsi/jitsi-meet-electron) or the Jitsi [mobile app](https://jitsi.org/downloads/). 22 | 23 | Use the little arrows in the control bar at the bottom to select speaker, microphone 24 | and camera in case you lack audio/video. 25 | 26 | ## Features 27 | 28 | ### Whiteboard and Etherpad 29 | 30 | The Jitsi instance has an etherpad and a whiteboard enabled. 31 | These tools can be used for collaborative creation and collection of content. 32 | Don't forget to save the contents to a persistent place after the meeting. 33 | 34 | ### Codecs 35 | 36 | It is configured to prefer video codecs [AV1](https://en.wikipedia.org/wiki/AV1) 37 | over [VP9](https://en.wikipedia.org/wiki/VP9) 38 | over [VP8](https://en.wikipedia.org/wiki/VP8) 39 | over [H.264](https://en.wikipedia.org/wiki/H.264/MPEG-4_AVC). 40 | It prefers the [opus](https://opus-codec.org/) audio codec. 41 | 42 | These settings are chosen to provide good video and audio quality for clients 43 | with modern hardware at moderate bandwidth requirements. 44 | Clients can chose to use older codecs without impacting audio or video streams 45 | of others. 46 | 47 | ## Dial-In 48 | 49 | Dial-In may be more stable for participants that have a stable phone connection, but 50 | not a reliable internet connection. 51 | 52 | We thus have an audio bridge using jigasi and [asterisk](https://www.asterisk.org/) 53 | connected to a [SIP](https://en.wikipedia.org/wiki/Session_Initiation_Protocol) provider. 54 | This allows a distinct set of rooms to be provided with phone dial-in. 55 | 56 | Here's the setup: 57 | 58 | | Room Name | Dial-in Suffix | 59 | | --------------- | -------------- | 60 | | SCS-Tech | 611 | 61 | | SCS-Governance | 612 | 62 | | Open-Operations | 613 | 63 | | SCS-OSISM | 614 | 64 | | SCS-Project | 615 | 65 | | SCS-Forum | 616 | 66 | | SCS-Kurt | 617 | 67 | | SCS-Taskforce | 618 | 68 | | SCS-ProjectTeam | 619 | 69 | 70 | Dial +49-221-292772-Suffix to connect. 71 | 72 | Rooms protected with a PIN would use 60x instead of 61x as suffix. 73 | Rooms with a three or four-digit number as room name would be connected to -61XXX or -61XXXX. 74 | Note that dial-in is not super-reliable due to occasional trouble with the SIP provider. 75 | So double-check ahead of important conference calls that require phone dial-in. Talk to Kurt 76 | to change room assignment or to resolve issues with dial-in. 77 | 78 | ## Browser specific hints 79 | 80 | Traditionally, the [blink](https://en.wikipedia.org/wiki/Blink_%28browser_engine%29)-based 81 | browsers (like Google Chrome, Chromium, Edge, ...) support WebRTC best. 82 | A Jitsi [desktop app](https://github.com/jitsi/jitsi-meet-electron) and Jitsi [mobile app](https://jitsi.org/downloads/) is also available. 83 | 84 | Safari and Firefox do work, but at the cost of inferior codecs or increased CPU or 85 | bandwidth requirements (e.g. due to missing [SimulCast](https://en.wikipedia.org/wiki/Simulcast) 86 | support or missing hardware acceleration). 87 | 88 | ### Firefox and VP9 / AV1 89 | 90 | On [Firefox](https://www.mozilla.org), in `about:config`, 91 | you can enable `media.peerconnection.video.vp9_preferred` and 92 | `media.webrtc.simulcast.vp9.enabled` for using VP9 video codec (which is better than VP8). 93 | 94 | By enabling experimental `media.webrtc.codec.video.av1.experimental_preferred` you even get AV1 95 | (which is even better) in Firefox 139+. Depending on whether your hardware has hardware support for VP9 96 | or AV1 encoding support and on whether that is exposed by your graphics driver stack, this may or may 97 | not create high CPU usage which you may not consider welcome as mobile user. 98 | 99 | ## Limitations and issues 100 | 101 | ### Firewalls blocking UDP traffic 102 | 103 | While the web interface uses https (port 8443) which most firewalls find acceptable, the audio and 104 | video is transmitted via UDP (port 10000+). Some corporate and many public sector firewalls believe 105 | that outgoing(!) UDP traffic is dangerous and needs to be intercepted. This means that our Jitsi 106 | setup will not work for participants behind such firewalls. 107 | (We do not currently have a [COTURN](https://github.com/coturn/coturn) server to work around this; 108 | instead we use other VC tools such as BB or OpenTalk or the tool of the partner.) 109 | 110 | ### Local audio 111 | 112 | A lack of audio is often in the local audio setup (mixer volumes turned to zero etc.). 113 | On Linux systems, the `pavucontrol` mixer may be the best starting point to resolve issues. 114 | 115 | ### Selective Stream forwarding failure 116 | 117 | Jitsi receives one or several audio and video streams from every participant and selectively 118 | forwards those to all recipients that have subscribed to these streams. (Typically, a low-res video 119 | stream is sent in addition to a medium-res and a high-res one — if any high-res subscribers exist). 120 | This approach to video-conferencing is called 121 | [selective forwarding unit (SFU)](https://bloggeek.me/webrtcglossary/sfu/). 122 | Occasionally, one of the participants can not hear one other (out of many) participants but everyone 123 | else can hear each other - a subscription to an audio (or video) stream may have gotten lost. 124 | In this case, a reconnect by the one not hearing is the best remedy. 125 | 126 | ### Large conferences 127 | 128 | For large conferences, it is recommended that participants stay muted and raise their hand 129 | in order to talk, so a moderator can ensure a somewhat structured discussion. While Jitsi can route 130 | a few dozens of video streams without trouble, the combined bandwidth may become a challenge for 131 | some of the participants and it is recommended to only switch on videos for the active participants. 132 | We have not tested much above 50 participants in the SCS community, so we don't know the precise limits 133 | of the server connection or capacity we use. 134 | 135 | ### Screen sharing frame rate 136 | 137 | Some browsers seem to ignore the FPS setting and try to transmit a shared window (or a shared 138 | desktop) at high resolution (e.g. 2560x1600) with 30fps. This requires more bandwidth than ADSL 139 | links typically handle. This can result in low-resolution streams rather than the (wanted) low-fps 140 | high-resolution stream. 141 | -------------------------------------------------------------------------------- /docusaurus.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Note: type annotations allow type checking and IDEs autocompletion 3 | 4 | import { themes as prismThemes } from 'prism-react-renderer' 5 | 6 | /** @type {import('@docusaurus/types').Config} */ 7 | const config = { 8 | title: 'One platform — standardized, built and operated by many.', 9 | tagline: 'Documentation and Community Platform for the Sovereign Cloud Stack', 10 | url: 'https://docs.scs.community', 11 | baseUrl: '/', 12 | onBrokenLinks: 'warn', 13 | onBrokenMarkdownLinks: 'warn', 14 | favicon: 'img/favicon.png', 15 | markdown: { 16 | mermaid: true 17 | }, 18 | organizationName: 'SovereignCloudStack', // Usually your GitHub org/user name. 19 | projectName: 'docs', // Usually your repo name. 20 | // Even if you don't use internalization, you can use this field to set useful 21 | // metadata like html lang. For example, if your site is Chinese, you may want 22 | // to replace "en" with "zh-Hans". 23 | i18n: { 24 | defaultLocale: 'en', 25 | locales: ['en'] 26 | }, 27 | presets: [ 28 | [ 29 | 'classic', 30 | /** @type {import('@docusaurus/preset-classic').Options} */ 31 | ({ 32 | docs: { 33 | sidebarPath: require.resolve('./sidebarsDocs.js'), 34 | editUrl: 'https://github.com/SovereignCloudStack/docs/tree/main/' 35 | }, 36 | blog: { 37 | showReadingTime: true, 38 | editUrl: 'https://github.com/SovereignCloudStack/docs/tree/main/' 39 | }, 40 | theme: { 41 | customCss: [require.resolve('./src/css/custom.css')] 42 | } 43 | }) 44 | ] 45 | ], 46 | plugins: [ 47 | [ 48 | '@docusaurus/plugin-client-redirects', 49 | { 50 | redirects: [ 51 | // { 52 | // to: '/community/collaboration', 53 | // from: '/community/calendar' 54 | // } 55 | ], 56 | createRedirects(existingPath) { 57 | if (existingPath.includes('/community')) { 58 | return [existingPath.replace('/community', '/community/community')] 59 | } 60 | return undefined // Return a falsy value: no redirect created 61 | } 62 | } 63 | ], 64 | [ 65 | '@docusaurus/plugin-content-docs', 66 | { 67 | id: 'community', 68 | path: 'community', 69 | routeBasePath: 'community', 70 | sidebarPath: require.resolve('./sidebarsCommunity.js') 71 | // ... other options 72 | } 73 | ], 74 | [ 75 | '@docusaurus/plugin-content-docs', 76 | { 77 | id: 'contributor-docs', 78 | path: 'contributor-docs', 79 | routeBasePath: 'contributor-docs', 80 | sidebarPath: require.resolve('./sidebarsContributorDocs.js') 81 | // ... other options 82 | } 83 | ], 84 | [ 85 | '@docusaurus/plugin-content-docs', 86 | { 87 | id: 'user-docs', 88 | path: 'user-docs', 89 | routeBasePath: 'user-docs', 90 | sidebarPath: require.resolve('./sidebarsUserDocs.js') 91 | // ... other options 92 | } 93 | ], 94 | [ 95 | '@docusaurus/plugin-content-docs', 96 | { 97 | id: 'standards', 98 | path: 'standards', 99 | routeBasePath: 'standards', 100 | sidebarPath: require.resolve('./sidebarsStandards.js') 101 | } 102 | ], 103 | './src/plugins/docusaurus-plugin-matomo-analytics/index.js', 104 | './src/plugins/docusaurus-plugin-global-data/index.js' 105 | ], 106 | 107 | themeConfig: 108 | /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ 109 | ({ 110 | metadata: [ 111 | { 112 | title: 'One platform — standardized, built and operated by many.', 113 | description: 114 | 'Documentation and Community Platform for the Sovereign Cloud Stack' 115 | } 116 | ], 117 | image: 'img/scs-og-basic.png', 118 | navbar: { 119 | title: '', 120 | logo: { 121 | alt: 'SCS', 122 | src: 'img/logo.svg' 123 | }, 124 | items: [ 125 | // { to: '/blog', label: 'Blog', position: 'left' }, 126 | { to: '/standards', label: 'Standards', position: 'left' }, 127 | { to: '/docs', label: 'For Operators', position: 'left' }, 128 | { 129 | to: '/contributor-docs', 130 | label: 'For Contributors', 131 | position: 'left' 132 | }, 133 | { 134 | to: '/user-docs', 135 | label: 'For Users', 136 | position: 'left' 137 | }, 138 | { to: '/community', label: 'Community', position: 'left' }, 139 | { to: '/docs/faq', label: 'FAQ', position: 'left' }, 140 | { 141 | href: 'https://github.com/SovereignCloudStack/docs', 142 | label: 'GitHub', 143 | position: 'right' 144 | } 145 | ] 146 | }, 147 | footer: { 148 | style: 'light', 149 | links: [ 150 | { 151 | title: 'Docs', 152 | items: [ 153 | { 154 | label: 'Contribute', 155 | to: '/docs' 156 | } 157 | ] 158 | }, 159 | { 160 | title: 'Community', 161 | items: [ 162 | { 163 | label: 'Matrix', 164 | href: 'https://matrix.to/#/!TiDqlLmEUaXqTemaLc:matrix.org?via=matrix.org' 165 | }, 166 | { 167 | label: 'Mastodon', 168 | href: 'https://fosstodon.org/@sovereigncloudstack' 169 | } 170 | ] 171 | }, 172 | { 173 | title: 'More', 174 | items: [ 175 | // { 176 | // label: 'Blog', 177 | // to: '/blog' 178 | // }, 179 | { 180 | label: 'GitHub', 181 | href: 'https://github.com/SovereignCloudStack/docs' 182 | } 183 | ] 184 | } 185 | ], 186 | copyright: 187 | 'Sovereign Cloud Stack, SCS and the logo are registered trademarks of the Open Source Business Alliance e.V. — Other trademarks are property of their respective owners.' 188 | }, 189 | prism: { 190 | theme: prismThemes.dracula, 191 | darkTheme: prismThemes.dracula, 192 | additionalLanguages: ['powershell', 'ruby'] 193 | }, 194 | matomoAnalytics: { 195 | matomoUrl: 'https://matomo.scs.community/', 196 | siteId: '2', 197 | phpLoader: 'matomo.php', 198 | jsLoader: 'matomo.js', 199 | disableCookies: true 200 | } 201 | }), 202 | 203 | themes: [ 204 | '@docusaurus/theme-mermaid', 205 | [ 206 | // @ts-ignore 207 | '@easyops-cn/docusaurus-search-local', 208 | /** @type {import('@easyops-cn/docusaurus-search-local').PluginOptions} */ 209 | // @ts-ignore 210 | ({ 211 | hashed: true, 212 | docsDir: [ 213 | 'docs', 214 | 'community', 215 | 'standards', 216 | 'contributor-docs', 217 | 'user-docs' 218 | ], 219 | docsRouteBasePath: [ 220 | 'docs', 221 | 'community', 222 | 'standards', 223 | 'contributor-docs', 224 | 'user-docs' 225 | ] 226 | }) 227 | ] 228 | ] 229 | } 230 | 231 | module.exports = config 232 | -------------------------------------------------------------------------------- /docs/02-iaas/deployment-examples/artcodix/index.mdx: -------------------------------------------------------------------------------- 1 | # artcodix 2 | 3 | ## Preface 4 | 5 | This document describes a possible environment setup for a pre-production or minimal production setup. 6 | In general hardware requirements can vary largely from environment to environment and this guide is not 7 | a hardware sizing guide nor the best placement solution of services for every setup. This guide intends to 8 | provide a starting point for a hardware based deployment of the SCS-IaaS reference implementation based on OSISM. 9 | 10 | ## Node type definitions 11 | 12 | ### Control Node 13 | 14 | A control node runs all or most of the openstack services, that are responsible for API-services and the corresponding 15 | runtimes. These nodes are necessary for any user to interact with the cloud and to keep the cloud in a managed state. 16 | However these nodes are usualy **not** running user virtual machines. 17 | Hence it is advisable to have the control nodes replicated. To have a RAFT-quorum three nodes are a good starting point. 18 | 19 | ### Compute Node (HCI/no HCI) 20 | 21 | #### Not Hyperconverged Infrastructure (no HCI) 22 | 23 | Non HCI compute nodes are exclusively running user virtual machines. They are running no API-services, no storage daemons 24 | and no network routers, except for the necessary network infrastructure to connect virtual machines. 25 | 26 | #### Hyperconverged Infrastructure (HCI) 27 | 28 | HCI nodes generally run at least user virtual machines and storage daemons. It is possible to place networking services 29 | here as well but that is not considered good practice. 30 | 31 | #### No HCI / vs HCI 32 | 33 | Whether to use HCI nodes or not is in general not an easy question. For a getting started (pre production/smalles possible production) 34 | environment however, it is the most cost efficent option. Therefore we will continue with HCI nodes (compute + storage). 35 | 36 | ### Storage Node 37 | 38 | A dedicated storage node runs only storage daemons. This can be necessary in larger deployments to protect the storage daemons from 39 | ressource starvation through user workloads. 40 | 41 | Not used in this setup. 42 | 43 | ### Network Node 44 | 45 | A dedicated network node runs the routing infrastructure for user virtual machines that connects these machines with provider / external 46 | networks. In larger deployments these can be useful to enhance scaling and improve network performance. 47 | 48 | Not used in this setup. 49 | 50 | ## Nodes in this deployment example 51 | 52 | As mentioned before we are running three dedicated control nodes. To be able to fully test an openstack environment it is 53 | recommended to run three compute nodes (HCI) as well. Technically you can get a setup running with just one compute node. 54 | See the following chapter (Use cases and validation) for more information. 55 | 56 | ### Use cases and validation 57 | 58 | The setup described allows for the following use cases / test cases: 59 | 60 | - Highly available control plane 61 | - Control plane failure toleration test (Database, RabbitMQ, Ceph Mons, Routers) 62 | - Highly available user virtual clusters (e.g. Kubernetes clusters) 63 | - Compute host failure simulation 64 | - Host aggregates / compute node grouping 65 | - Host based storage replication (instead of OSD based) 66 | - Fully replicated storage / storage high availability test 67 | 68 | ### Control Node 69 | 70 | #### General requirements 71 | 72 | The control nodes do not run any user workloads. This means they are usually not sized as big as the compute nodes. 73 | Relevant metrics for control nodes are: 74 | 75 | - Fast and big enough discs. At least SATA-SSDs are recommended, NVMe will greatly improve the overall responsiveness. 76 | - A rather large amount of memory to house all the caches for databases and queues. 77 | - CPU performance should be average. A good compromise between amount of cores and speed should be used. However this is 78 | the least important requirement on the list. 79 | 80 | #### Hardware recommendation 81 | 82 | The following server specs are just a starting point and can greatly vary between environments. 83 | 84 | Example: 85 | 3x Dell R630/R640/R650 1HE Server 86 | 87 | - Dual 8 Core 3,00 GHz Intel/AMD 88 | - 128 GB RAM 89 | - 2x 3,84 TB NVMe in (Software-) RAID 1 90 | - 2x 10/25/40 GBit 2 Port SFP+/QSFP Network Cards 91 | 92 | ### Compute Node (HCI) 93 | 94 | The compute nodes in this scenario run all the user virtual workloads **and** the storage infrastructure. To make sure 95 | we don't starve these nodes, they should be of decent size. 96 | 97 | > This setup takes local storage tests into consideration. The SCS-standards require certain flavors with very fast disc speed 98 | > to house customer kubernetes control planes (etcd). These speeds are usually not achievable with shared storage. If you don't 99 | > intend to test this scenario, you can skip the NVMe discs. 100 | 101 | #### Hardware recommendation 102 | 103 | The following server specs are just a starting point and can greatly vary between environments. The sizing of the nodes needs to fit 104 | the expected workloads (customer VMs). 105 | 106 | Example: 107 | 3x Dell R730(xd)/R740(xd)/R750(xd) 108 | or 109 | 3x Supermicro 110 | 111 | - Dual 16 Core 2,8 GHz Intel/AMD 112 | - 512 GB RAM 113 | - 2x 3,84 TB NVMe in (Software-) RAID 1 if you want to have local storage available (optional) 114 | 115 | For hyperconverged ceph osds: 116 | 117 | - 4x 10 TB HDD -> This leads to ~30 TB of available HDD storage (optional) 118 | - 4x 7,68 TB SSD -> This leads to ~25 TB of available SSD storage (optional) 119 | - 2x 10/25/40 GBit 2 Port SFP+/QSFP Network Cards 120 | 121 | ## Network 122 | 123 | The network infrastructure can vary a lot from setup to setup. This guide does not intend to define the best networking solution 124 | for every cluster but rather give two possible scenarios. 125 | 126 | ### Scenario A: Not recommended for production 127 | 128 | The smallest possible setup is just a single switch connected to all the nodes physically on one interface. The switch has to be 129 | VLAN enabled. Openstack recommends multiple isolated networks but the following are at least recommended to be split: 130 | 131 | - Out of Band network 132 | - Management networks 133 | - Storage backend network 134 | - Public / External network for virutal machines 135 | If there is only one switch, these networks should all be defined as seperate VLANs. One of the networks can run in untagged default 136 | VLAN 1. 137 | 138 | ### Scenario B: Minimum recommended setup for small production environments 139 | 140 | The recommended setup uses two stacked switches connected in a LAG and at least three different physical network ports on each node. 141 | 142 | - Physical Network 1: VLANs for Public / External network for virutal machines, Management networks 143 | - Physical Network 2: Storage backend network 144 | - Physical Network 3: Out of Band network 145 | 146 | ### Network adapters 147 | 148 | The out of band network does usually not need a lot of bandwith. Most modern servers come with 1Gbit/s adapters which are sufficient. 149 | For small test clusters, it might also be sufficient to use 1Gbit/s networks for the other two physical networks. 150 | For a minimum production cluster it is recommended to use the following: 151 | 152 | - Out of Band Network: 1Gbit/s 153 | - VLANs for Public / External network for virutal machines, Management networks: 10 / 25 Gbit/s 154 | - Storage backend network: 10 / 25 / 40 Gbit/s 155 | 156 | Whether you need a higher throughput for your storage backend services depends on your expected storage load. The faster the network 157 | the faster storage data can be replicated between nodes. This usually leads to improved performance and better/faster fault tolerance. 158 | 159 | ## How to continue 160 | 161 | After implementing the recommended deployment example hardware, you can continue with the [deployment guide](https://docs.scs.community/docs/iaas/guides/deploy-guide/). 162 | --------------------------------------------------------------------------------